home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / PartMaker 4.3 / Window.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-12  |  77.3 KB  |  2,794 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        Window.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1990-1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19. /* This file contains the code for the document procedure pointers for the main Wannabe
  20. ** document.  Wannabe currently only supports one type of documents, type 'DUMD',
  21. ** which stands for "DUMb Document". */
  22.  
  23. /* For more information on this file, please read the read.me file "=How to write your app". */ 
  24.  
  25.  
  26.  
  27. /*****************************************************************************/
  28.  
  29.  
  30.  
  31. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  32. #include "App.defs.h"        /* Get various application definitions.            */
  33. #include "App.protos.h"        /* Get the prototypes for application.            */
  34.  
  35. #ifndef __ERRORS__
  36. #include <Errors.h>
  37. #endif
  38.  
  39. #ifndef __FINDER__
  40. #include <Finder.h>
  41. #endif
  42.  
  43. #ifndef __FONTS__
  44. #include <Fonts.h>
  45. #endif
  46.  
  47. #ifndef __RESOURCES__
  48. #include <Resources.h>
  49. #endif
  50.  
  51. #ifndef __TOOLUTILS__
  52. #include <ToolUtils.h>
  53. #endif
  54.  
  55. #ifndef __UTILITIES__
  56. #include "Utilities.h"
  57. #endif
  58.  
  59. #ifdef powerc
  60. #pragma options align=mac68k
  61. #endif
  62. typedef struct xFSSpec {
  63.     FSSpec    **fss;
  64.     Str32    oldName;
  65. } xFSSpec;
  66. #ifdef powerc
  67. #pragma options align=reset
  68. #endif
  69.  
  70.  
  71.  
  72. /*****************************************************************************/
  73.  
  74.  
  75.  
  76. extern TreeObjHndl        gWindowFormats;
  77.  
  78. static void        CreatePart(WindowPtr window);
  79. static void        FixupAliases(WindowPtr window);
  80. static OSErr    FullPathFromAlias(AliasHandle alias, StringPtr aliasPath, StringPtr aliasName);
  81. static OSErr    FullPathFromFSSpec(const FSSpec *spec, StringPtr fsPath, StringPtr fsName);
  82.  
  83. static void        MyFindText(long *offset);
  84. static void        MyReplaceText(long *offset);
  85. static void        FixNMAPs(StringPtr pstr, StringPtr qstr);
  86. static void        MergeCustomResources(short out, short in);
  87.  
  88. static void        IndCNum2Ctl(WindowPtr window, short cnum, short cset, ControlHandle *ctl);
  89. static void        VisCNum2Ctl(WindowPtr window, short cnum, ControlHandle *ctl);
  90.  
  91. static char        *gText;
  92. static char        *gFText;
  93. static char        *gRText;
  94. static long        gLen, gFLen, gRLen;
  95. static Boolean    gOpenedDoc, gNoReplace;
  96. static short    gDataSetBase = 5000;
  97.  
  98. static xFSSpec        gFSSpec[512];
  99. static AliasHandle    gAlias[128];
  100. static short        gResolveIndx;
  101.  
  102. static OSErr    CacheFile(FSSpec out, FSSpec in, short *oldDepth, short newDepth);
  103. static short    gRsrcNum;
  104.  
  105. Boolean        gNoDefaultDocument = false;
  106.                     /* Set to true if app should boot with no default document. */
  107.                     /* This tells DTS.Lib..framework what you want. */
  108.  
  109. OSType        gAppWindowType = kDocFileType;    /* Main document type. */
  110. long        gAppWindowAttr = kwAppWindow;    /* Main window attributes. */
  111.  
  112. short        gMinVersion    = kMinVersion;    /* Minimum document version app can support. */
  113. short        gMaxVersion    = kMaxVersion;    /* Maximum document version app can support. */
  114.                                             /* More informing DTS.Lib..framework. */
  115.  
  116. extern short        gPrintPage;                /* Non-zero means we are printing. */
  117.                                             /* DTS.Lib..framework global. */
  118.  
  119. extern RgnHandle    gCursorRgn;                /* We handle cursors here, so we need */
  120. extern CursPtr        gCursorPtr;                /* to know about these things. */
  121.                                             /* Above are DTS.Lib..framework globals. */
  122.  
  123. /* Currently Wannabe doesn't ever change the cursor, so we don't actually need
  124. ** these referenced here.  However, since Wannabe is supposed to be an application
  125. ** in progress, it is very likely that you will need to reference these as your
  126. ** project develops.  See DTS.StyleChat and DTS.Draw for examples of setting the cursor. */
  127.  
  128. /* Some cursors are pointer-based, and some cursors are resource-based.
  129. ** If a cursor is resource-based, it needs to be loaded and made to not move,
  130. ** and then gCursorPtr can be set to point to it.  This makes all cursors
  131. ** pointer-based.  Also, gCursorPtr is used by DTS.Lib..framework to
  132. ** determine if there is a current cursor.  If gCursorPtr is nil, then
  133. ** there is no current cursor, and the cursor has to be recalculated, no
  134. ** matter where the mouse is.  If gCursorPtr is not nil, then if the
  135. ** mouse position is within the cursor region gCursorRgn, the cursor is
  136. ** correct, and no recalculation is necessary.  If it is outside this region,
  137. ** then it is recalculated.  What does this all mean?  It means that if you
  138. ** want to guarantee that the cursor is recalculated next time DoWindowCursor()
  139. ** is called, set gCursorPtr to nil.
  140. **
  141. ** If you have a cursor resource, you need to:
  142. ** 1) Load the resource.
  143. ** 2) Make a fixed copy of it.
  144. ** 3) Set the cursor to it.
  145. ** 4) Set gCursorPtr to point to the fixed copy.
  146. **
  147. ** There is a function that does almost all of this, called DoSetResCursor().
  148. ** It does all but set gCursorPtr to it.  (It actually sets gCursorPtr to nil.)
  149. ** It does return a pointer to the permanent copy, so typically what you will
  150. ** want to do is the following:
  151. **     gCursorPtr = DoSetResCursor(theCursorID);
  152. **
  153. ** So why set gCursorPtr to nil as the default action?  This allows you to
  154. ** set a temporary cursor, which will be replaced when DoWindowCursor() is
  155. ** called next, or it allows you to set a cursor that maps to the cursor
  156. ** region gCursorRgn (by setting gCursorPtr to the return result). */
  157.  
  158.  
  159.  
  160. /*****************************************************************************/
  161. /*****************************************************************************/
  162.  
  163. #ifdef applec
  164. #pragma segment Window
  165. #endif
  166.  
  167. /*****************************************************************************/
  168. /*****************************************************************************/
  169.  
  170.  
  171.  
  172. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  173.  
  174. /* Calculate application specific frame area (Called by DoCalcFrameRgn).
  175. ** You are passed an empty region.  You are supposed to add any custom frame
  176. ** parts that this document uses.  Typically there are no frame portions, as
  177. ** they are accounted for in other ways.  The scrollbars and grow icon will
  178. ** automatically be contributed to the calculation of the frame region.
  179. ** If you use sidebars, these are also added in automatically.  This is only
  180. ** used if the frame region is more complicated than can automatically be
  181. ** handled.  So, almost always, you will simply leave the region empty. */
  182.  
  183. void    CalcFrameRgn(FileRecHndl frHndl, WindowPtr window, RgnHandle rgn)
  184. {
  185. #ifndef __MWERKS__
  186. #pragma unused (frHndl, window, rgn)
  187. #endif
  188. }
  189.  
  190.  
  191.  
  192. /*****************************************************************************/
  193.  
  194.  
  195.  
  196. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  197.  
  198. /* This is called (by DoContentClick()) when a mouse-down event occurs in the content of
  199. ** a window.  Other applications might want to call FindControl, TEClick, etc., to
  200. ** further process the click. */
  201.  
  202. void    ContentClick(WindowPtr window, EventRecord *event, Boolean firstClick)
  203. {
  204. #ifndef __MWERKS__
  205. #pragma unused (firstClick)
  206. #endif
  207.  
  208.     ControlHandle    ctl;
  209.     short            action, cnum, oldRes, modifiers, optkey, numAdded;
  210.     FileRecHndl        frHndl, aboutDoc;
  211.     OSErr            err;
  212.  
  213.     frHndl = (FileRecHndl)GetWRefCon(window);
  214.     PrepDocResFile(frHndl, &oldRes, fsRdPerm);
  215.  
  216.     cnum = IsCtlEvent(window, event, &ctl, &action);
  217.         /* That was easy.  Scrolling was just handled.  Other stuff would be handled
  218.         ** by IsCtlEvent, if we had other stuff to do.  We don't have any other
  219.         ** controls in the content besides the document scrollbars. */
  220.  
  221.     if (cnum == kWhichDataSet) {
  222.         VisCNum2Ctl(window, kNewClassName, &ctl);
  223.         if (ctl) {
  224.             CTESetSelect(0, 32767, (TEHandle)GetControlReference(ctl));
  225.             CTEActivate(true, (TEHandle)GetControlReference(ctl));
  226.         }
  227.     }
  228.  
  229.     if (cnum == kAboutDocument) {
  230.         err = GetSeparateWFMT('ABTD', &numAdded);
  231.         if (!err) {
  232.             err = NewDocument(&aboutDoc, 'ABTD', false);
  233.             if (!err) {
  234.                 err = DoNewWindow(aboutDoc, nil, window, (WindowPtr)-1);
  235.                 if (err) DisposeDocument(aboutDoc);
  236.             }
  237.         }
  238.         GetSeparateWFMT(0, &numAdded);
  239.     }
  240.  
  241.     if (cnum == -1) {
  242.         modifiers = event->modifiers;
  243.         optkey    = (modifiers & optionKey);
  244.         if (optkey) gNoReplace = true;
  245.         CreatePart(window);
  246.         FixupAliases(window);
  247.     }
  248.     gNoReplace = false;
  249.  
  250. //    CloseDocResFile(frHndl);
  251.     UseResFile(gAppResRef);
  252.  
  253.     return;
  254. }
  255.  
  256.  
  257.  
  258. /*****************************************************************************/
  259.  
  260.  
  261.  
  262. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  263.  
  264. /* DoKeyDown() is first called by the application.  Then if the key isn't a menu
  265. ** key, DoKeyDown() calls this code.  Here are the rules for this function:
  266. **
  267. ** 1) If you handle the key, return(true).  This completes the key handling.
  268. ** 2) If you don't handle the key, you return false.  However, there are two
  269. **    situations for not handling the key:
  270. **      a) You want someone else to.
  271. **      b) You want nobody else to look at the key.
  272. **    This is what the boolean passThrough is for.  If you wish the next window
  273. **    to have a look at the key, set the boolean passThrough to true.  passThrough
  274. **    is already initialized to false, which is the common case, so you only have
  275. **    to worry about setting it true.
  276. **
  277. ** If you have a window that never processes keys and always passes them through,
  278. ** just set the contentKeyProc to nil.  This will indicate to the application
  279. ** framework that all keys should be passed through this window.  DTS.Draw has
  280. ** such a window.  Its palette window doesn't accept keys.  They are passed through
  281. ** to document windows. */
  282.  
  283. Boolean    ContentKey(WindowPtr window, EventRecord *event, Boolean *passThrough)
  284. {
  285. #ifndef __MWERKS__
  286. #pragma unused (passThrough)
  287. #endif
  288.  
  289.     short        cnum, oldRes, numAdded;
  290.     OSErr        err;
  291.     FileRecHndl    frHndl, aboutDoc;
  292.  
  293.     frHndl = (FileRecHndl)GetWRefCon(window);
  294.     PrepDocResFile(frHndl, &oldRes, fsRdPerm);
  295.  
  296.     cnum = IsCtlEvent(window, event, nil, nil);
  297.         /* See DTS.Draw for an example of what you might do here. */
  298.  
  299.     if (cnum == -1) {
  300.         CreatePart(window);
  301.         FixupAliases(window);
  302.     }
  303.  
  304.     if (cnum == kAboutDocument) {
  305.         err = GetSeparateWFMT('ABTD', &numAdded);
  306.         if (!err) {
  307.             err = NewDocument(&aboutDoc, 'ABTD', false);
  308.             if (!err) {
  309.                 err = DoNewWindow(aboutDoc, nil, window, (WindowPtr)-1);
  310.                 if (err) DisposeDocument(aboutDoc);
  311.             }
  312.         }
  313.         GetSeparateWFMT(0, &numAdded);
  314.     }
  315.  
  316. //    CloseDocResFile(frHndl);
  317.     UseResFile(gAppResRef);
  318.  
  319.     return(true);
  320. }
  321.  
  322.  
  323.  
  324. /*****************************************************************************/
  325.  
  326.  
  327.  
  328. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  329.  
  330. /* Draw application specific content (Called by DoDrawFrame).
  331. **
  332. ** If your application has any custom frame areas, or if it uses sidebars,
  333. ** this is the function that you would put the frame drawing code.  The
  334. ** document scrollbars and grow icon drawing is handled by DTS.framework.
  335. ** Just do the sidebar and custom areas here. */
  336.  
  337. void    DrawFrame(FileRecHndl frHndl, WindowPtr window, Boolean activate)
  338. {
  339.     MoveTo(0, (*frHndl)->fileState.topSidebar - 1);
  340.     LineTo((*frHndl)->fileState.leftSidebar - 1 - 16384, (*frHndl)->fileState.topSidebar - 1);
  341.     LineTo((*frHndl)->fileState.leftSidebar - 1 - 16384, 16383);
  342.  
  343.     BeginFrame(window);
  344.     DoDrawControls(window, activate);
  345.     EndFrame(window);
  346. }
  347.  
  348.  
  349.  
  350. /*****************************************************************************/
  351.  
  352.  
  353.  
  354. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  355.  
  356. /* Frees up any application-specific memory in the document.  This is called by
  357. ** DoFreeDocument, which is called by DisposeDocument().  The application would
  358. ** call DisposeDocument(), not DoFreeDocument() or FreeDocument() directly.
  359. **
  360. ** The document may have a bunch of handles off the main handle of the document.
  361. ** This is where they are freed.  DisposeDocument calls this prior to releasing
  362. ** the ram for the main handle of the document, so release everything else
  363. ** here, or you will have a memory leak.
  364. **
  365. ** NOTE:  Calling DefaultFreeDocument() frees up all memory used by a
  366. ** hierarchical document (see TreeObj package). */
  367.  
  368. OSErr    FreeDocument(FileRecHndl frHndl)
  369. {
  370.     return(DefaultFreeDocument(frHndl));
  371. }
  372.  
  373.  
  374.  
  375. /*****************************************************************************/
  376.  
  377.  
  378.  
  379. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  380.  
  381. /* Any additional window disposal tasks can be handled here. */
  382.  
  383. OSErr    FreeWindow(FileRecHndl frHndl, WindowPtr window)
  384. {
  385. #ifndef __MWERKS__
  386. #pragma unused (window)
  387. #endif
  388.  
  389.     WindowPtr    ww;
  390.     FileRecHndl    ff;
  391.  
  392.     if ((*frHndl)->fileState.sfType == 'PtMd') {
  393.         for (ww = nil; (ww = GetNextDocumentWindow(ww, 0)) != nil;) {
  394.             ff = (FileRecHndl)GetWRefCon(ww);
  395.             if ((*ff)->fileState.sfType == kViewHierFileType) {
  396.                 if ((*frHndl)->d.doc.root == (*ff)->d.doc.root) {
  397.                     DisposeOneWindow(ww, kClose);
  398.                     ww = nil;
  399.                 }
  400.             }
  401.         }
  402.     }
  403.  
  404.     return(noErr);
  405. }
  406.  
  407.  
  408.  
  409. /*****************************************************************************/
  410.  
  411.  
  412.  
  413. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  414.  
  415. /* Image the document into the current port.
  416. **
  417. ** The only thing tricky about this function is that it needs to key off of
  418. ** the global variable gPrintPage.  gPrintPage is the current page that is
  419. ** being printed.  If gPrintPage is 0, then you are drawing to the window.
  420. **
  421. ** For when printing:
  422. **
  423. ** If gPrintPage is non-0, that is the page to be printed.  If after imaging
  424. ** the page there are no more pages, you should set gPrintPage to 0.  This
  425. ** indicates to the print loop that the end of the document has been reached.
  426. ** Even if the user indicated in the job dialog to print more pages, setting
  427. ** gPrintPage to 0 states that the last page has been printed.  This is necessary
  428. ** because the print loop can't know when printing is done.  The imaging procedure
  429. ** is the logical one to state when everything has been imaged. */
  430.  
  431. OSErr    ImageDocument(FileRecHndl frHndl)
  432. {
  433. #ifndef __MWERKS__
  434. #pragma unused (frHndl)
  435. #endif
  436.  
  437.     short    oldRes;
  438.  
  439.     PrepDocResFile(frHndl, &oldRes, fsRdPerm);
  440.  
  441.     DoDrawControls((*frHndl)->fileState.window, false);        /* Draw the content controls. */
  442.     gPrintPage = 0;
  443.  
  444.     UseResFile(oldRes);
  445.  
  446.     return(noErr);
  447. }
  448.  
  449.  
  450.  
  451. /*****************************************************************************/
  452.  
  453.  
  454.  
  455. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  456.  
  457. /* This function does the remaining window initialization.
  458. **
  459. ** There may be additional content initialization for the window.  At this point,
  460. ** you have a window, but it is currently invisible.  If you return noErr, then
  461. ** the window will be set to the state indicated for that window.  Why this function?
  462. ** You may wish to add controls to the content of the window.  You may have a
  463. ** TextEdit record in the content.  All of these sort of things can't be created
  464. ** until there is a window to contain them.  First a document is read in, and then
  465. ** if the document creation succeeds, a window is created for that document.
  466. ** At this point we have a document, and we are on our way to having a window.
  467. ** All that remains is any additional content initialization.  Do it, return
  468. ** noErr, and everybody's happy.  If something goes wrong here, return the error,
  469. ** and the incomplete window will be disposed of. */
  470.  
  471. Boolean    ProperClassName(TEHandle teHndl, EventRecord *event, short *handled);
  472. OSErr    InitContent(FileRecHndl frHndl, WindowPtr window)
  473. {
  474.     OSErr            err;
  475.     ControlHandle    ctl, cc, aw;
  476.     TEHandle        te;
  477.     short            oldRes, numAdded, cset;
  478.     Str255            pstr;
  479.     StringHandle    sh;
  480.  
  481.     err = noErr;
  482.  
  483.     if ((*frHndl)->fileState.sfType == 'PtMd') {
  484.  
  485.         err = PrepDocResFile(frHndl, &oldRes, fsRdPerm);
  486.         if (err) return(err);
  487.  
  488.         GetSeparateWFMT('PtMd', &numAdded);
  489.         err = AddControlSet(window, (*frHndl)->fileState.sfType, kwStandardVis, 0, 0, nil);
  490.         GetSeparateWFMT(0, &numAdded);
  491.  
  492.         if (err) {
  493.             CloseDocResFile(frHndl);
  494.             UseResFile(gAppResRef);
  495.             return(err);
  496.         }
  497.  
  498.         for (cset = 1;; ++cset) {
  499.             IndCNum2Ctl(window, kNewClassName, cset, &ctl);
  500.                 /* IndCNum2Ctl gets the controlof id/refcon, which
  501.                 ** in this case is kNewClassName/cset. */
  502.             if ((!ctl) && (cset)) break;
  503.             if (!ctl)             continue;
  504.             te = (TEHandle)GetControlReference(ctl);
  505.             IndCNum2Ctl(window, kAppWannabeCreator, cset, &aw);
  506.             if (!aw) CTESetKeyFilter(te, ProperClassName);
  507.  
  508.             IndCNum2Ctl(window, kOldClassName, cset, &cc);
  509.             if (cc) {
  510.                 pcpy(pstr, (*cc)->contrlTitle);
  511.                 CTEPutPStr(ctl, pstr);
  512.                 CTESetSelect(0, 32767, (TEHandle)GetControlReference(ctl));
  513.             }
  514.             else {
  515.                 sh = GetString(5000);
  516.                 pcpy(pstr, *sh);
  517.                 pstr[1] = pstr[0] - 1;
  518.                 CTEPutPStr(ctl, pstr + 1);
  519.                 CTESetSelect(0, 32767, (TEHandle)GetControlReference(ctl));
  520.             }
  521.         }
  522.  
  523.         for (cset = 1;; ++cset) {
  524.             IndCNum2Ctl(window, kNewCompanyName, cset, &ctl);
  525.             if ((!ctl) && (cset)) break;
  526.             if (!ctl)             continue;
  527.  
  528.             te = (TEHandle)GetControlReference(ctl);
  529.             CTESetKeyFilter(te, ProperClassName);
  530.             IndCNum2Ctl(window, kOldCompanyName, cset, &cc);
  531.             if (cc) {
  532.                 pcpy(pstr, (*cc)->contrlTitle);
  533.                 CTEPutPStr(ctl, pstr);
  534.                 CTESetSelect(0, 32767, (TEHandle)GetControlReference(ctl));
  535.             }
  536.         }
  537.  
  538. //        CloseDocResFile(frHndl);
  539.         UseResFile(gAppResRef);
  540.  
  541.         gOpenedDoc = true;
  542.         return(noErr);
  543.     }
  544.  
  545.     return(err);
  546. }
  547.  
  548. Boolean    ProperClassName(TEHandle te, EventRecord *event, short *handled)
  549. {
  550.     char    key;
  551.     short    i;
  552.     Boolean    validChar;
  553.  
  554.     key = event->message   & charCodeMask;
  555.     i   = event->modifiers & keyCodeMask;
  556.     if (i & cmdKey)                    return(false);
  557.     if (i & optionKey)                return(false);
  558.     if (key == 8)                    return(false);
  559.     if (key == 9)                    return(false);
  560.     if ((key >= 28) && (key <= 31)) return(false);
  561.  
  562.     validChar = false;
  563.     if ((key >= 'A') && (key <= 'Z')) validChar = true;
  564.     if ((key >= 'a') && (key <= 'z')) validChar = true;
  565.     if ((*te)->selStart) {
  566.         if ((key >= '0') && (key <= '9')) validChar = true;
  567.         if (key == '_')                      validChar = true;
  568.     }
  569.     if (validChar) return(false);
  570.  
  571.     return(true);
  572. }
  573.  
  574. void    DoFolders(void)
  575. {
  576.     WindowPtr        window, rww;
  577.     FileRecHndl        frHndl, rff;
  578.     OSErr            err;
  579.     Boolean         isDirectory;
  580.     FSSpec            fss, fssd, matches[1];
  581.     long            mcount;
  582.     short            iloc, p1, p2, pp, res, oldRes, oldRes2, i;
  583.     long            pid[128];
  584.     TreeObjHndl        cobj;
  585.  
  586.     oldRes = CurResFile();
  587.  
  588.     DoSetResCursor(watchCursor);
  589.  
  590.     for (i = (*gWindowFormats)->numChildren; i; ) {
  591.         cobj = GetChildHndl(gWindowFormats, --i);
  592.         if (mDerefWFMT(cobj)->sfType == 'fold') break;
  593.     }
  594.     if (!i) return;
  595.  
  596.     for (;;) {
  597.  
  598.         window = GetNextDocumentWindow(nil, 'fold');
  599.         if (!window) break;
  600.         frHndl = (FileRecHndl)GetWRefCon(window);
  601.  
  602.         fss  = (*frHndl)->fileState.fss;
  603.         fssd = fss;
  604.         err  = DirIDFromFSSpec(&fss, &fssd.parID, &isDirectory);
  605.  
  606.         if (fss.name[0] == 31) fss.name[0]--;
  607.         pcat(fss.name, "\p•");
  608.  
  609.         p1 = pp   = 0;
  610.         pid[pp++] = matches[0].parID;
  611.         iloc      = 0;
  612.         gRsrcNum  = 5000;
  613.         do {
  614.             err = FindEverything(fssd.vRefNum, fssd.parID, matches, 1, &mcount, false);
  615.             if (mcount) {
  616.                 for (p2 = 0; p2 < pp; ++p2) if (pid[p2] == matches[0].parID) break;
  617.                 pid[p2++] = matches[0].parID;
  618.                 pp = p2;
  619.                 CacheFile(fss, matches[0], &p1, p2);
  620.             }
  621.         } while (err == noErr);
  622.  
  623.         res = HOpenResFile(fss.vRefNum, fss.parID, fss.name, fsRdWrPerm);
  624.         err = ResError();
  625.         if (!err) {
  626.             for (rww = nil; (rww = GetNextDocumentWindow(rww, 'rsrc')) != nil;) {
  627.                 rff = (FileRecHndl)GetWRefCon(rww);
  628.                 if (!UseDocResFile(rff, &oldRes2, fsRdPerm)) {
  629.                     MergeCustomResources(res, CurResFile());
  630.                     CloseDocResFile(rff);
  631.                     UseResFile(oldRes2);
  632.                 }
  633.             }
  634.             for (rww = nil; (rww = GetNextDocumentWindow(rww, 'RSRC')) != nil;) {
  635.                 rff = (FileRecHndl)GetWRefCon(rww);
  636.                 if (!UseDocResFile(rff, &oldRes2, fsRdPerm)) {
  637.                     MergeCustomResources(res, CurResFile());
  638.                     CloseDocResFile(rff);
  639.                     UseResFile(oldRes2);
  640.                 }
  641.             }
  642.         }
  643.  
  644.         DisposeOneWindow(window, kClose);
  645.     }
  646.  
  647.     UseResFile(oldRes);
  648. }
  649.  
  650. void    MergeCustomResources(short out, short in)
  651. {
  652.     short        tt, ii, nt, ni, rid;
  653.     ResType        rtype;
  654.     Str255        rname;
  655.     char        rattr;
  656.     Handle        rr, oldr;
  657.  
  658.     UseResFile(in);
  659.     nt = Count1Types();
  660.  
  661.     for (tt = nt; tt; --tt) {
  662.  
  663.         Get1IndType(&rtype, tt);
  664.         ni = Count1Resources(rtype);
  665.  
  666.         for (ii = ni; ii; --ii) {
  667.  
  668.             rr = Get1IndResource(rtype, ii);
  669.             if (!rr) continue;
  670.  
  671.             GetResInfo(rr, &rid, &rtype, rname);
  672.             rattr = GetResAttrs(rr);
  673.  
  674.             DetachResource(rr);
  675.             UseResFile(out);
  676.  
  677.             oldr = Get1Resource(rtype, rid);
  678.             if (oldr) {
  679.                 RemoveResource(oldr);
  680.                 DisposeHandle(oldr);
  681.             }
  682.  
  683.             AddResource(rr, rtype, rid, rname);
  684.             SetResAttrs(rr, rattr);
  685.             ChangedResource(rr);
  686.             WriteResource(rr);
  687.             DetachResource(rr);
  688.             DisposeHandle(rr);
  689.  
  690.             UseResFile(in);
  691.         }
  692.     }
  693. }
  694.  
  695.  
  696.  
  697. /*****************************************************************************/
  698.  
  699.  
  700.  
  701. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  702.  
  703. /* The code below assumes that you are using the hierarchical document package.
  704. ** If you are, the entire hierarchical document is read in with just these two
  705. ** calls.  If you don't use it, you are on your own.  See DTS.StyleChat for an
  706. ** example of an application that uses the DTS.framework without the hierarchical
  707. ** document package. */
  708.  
  709. OSErr    ReadDocument(FileRecHndl frHndl)
  710. {
  711.     return(noErr);
  712. }
  713.  
  714.  
  715.  
  716. /*****************************************************************************/
  717.  
  718.  
  719.  
  720. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  721.  
  722. /* Resize application specific content (Called by ResizeWindow).
  723. **
  724. ** This gets called when a user does a zoom or window resizing operation.
  725. ** It is possible that things in the content need to be resized in conjunction
  726. ** with the resizing of the window. */
  727.  
  728. void    ResizeContent(WindowPtr window, short oldh, short oldv)
  729. {
  730. #ifndef __MWERKS__
  731. #pragma unused (window, oldh, oldv)
  732. #endif
  733.  
  734.     /* See DTS.StyleChat for a sample usage of this function. */
  735. }
  736.  
  737.  
  738.  
  739. /*****************************************************************************/
  740.  
  741.  
  742.  
  743. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  744.  
  745. /* Scroll application specific frame (Called by DoScrollFrame).
  746. **
  747. ** Some applications may need to scroll the "frame" of the document along
  748. ** with the document contents.  This is common for applications with rulers,
  749. ** or other similar sidebar items. */
  750.  
  751. void    ScrollFrame(FileRecHndl frHndl, WindowPtr window, long dh, long dv)
  752. {
  753. #ifndef __MWERKS__
  754. #pragma unused (frHndl, window, dh, dv)
  755. #endif
  756. }
  757.  
  758.  
  759.  
  760. /*****************************************************************************/
  761.  
  762.  
  763.  
  764. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  765.  
  766. /* Since the hierarchical document package isn't used by DTS.StyleChat,
  767. ** this function actually never gets called. */
  768.  
  769. void    UndoFixup(FileRecHndl frHndl, Point contOrg, Boolean afterUndo)
  770. {
  771. #ifndef __MWERKS__
  772. #pragma unused (frHndl, contOrg, afterUndo)
  773. #endif
  774.  
  775.     /* See DTS.Draw for an example of what you might do here. */
  776. }
  777.  
  778.  
  779.  
  780. /*****************************************************************************/
  781.  
  782.  
  783.  
  784. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  785.  
  786. /* This function is where you adjust the cursor to reflect the location in the
  787. ** document or window.  You have the additional input of gCursorRgn to deal
  788. ** with.  The way that the cursor handling works is as follows:
  789. ** 1) The application calls DoWindowCursor().
  790. ** 2) DoWindowCursor() works its way through the windows/documents, front to back.
  791. **    It looks at the document's windowCursorProc and checks to see if the document
  792. **    has one.  If the document doesn't have one, then it assumes that that window
  793. **    always wants an arrow.  If the cursor is over that window, the cursor is set
  794. **    to an arrow, and we're done.  If the cursor isn't over the window, then the next
  795. **    window is tried.  If all documents don't have a windowCursorProc, then the cursor
  796. **    is set to an arrow (for the non-document area of the screen).
  797. ** 3) If a document has a windowCursorProc, then the proc is called.  The proc's
  798. **    job is as follows:
  799. **    a) If the cursor is over a position that is determined by the window, then
  800. **       the proc removes other areas from gCursorRgn.  Note that it should not
  801. **       simply set the area to what it "thinks" is the correct area.  This window
  802. **       may not be the front-most.  Other windows will have already been subtracted
  803. **       from gCursorRgn.  The resultant gCursorRgn is the correct cursor area,
  804. **       and should be passed to WaitNextEvent calls in the application (already the case
  805. **       in EventLoop.c).  Also, the cursor should be set to the correct cursor, of course.
  806. **       You should also return true, as the cursor has been determined.
  807. **    b) If the cursor is not over a position for this window, then you should
  808. **       return.  You will either pass back true or false.  If you don't wish
  809. **       windows behind this window to have a shot at cursor determination, then
  810. **       return true.  This states that the cursor is "determined".  It is, in the
  811. **       sense that no further determination will occur.  If you return false, then
  812. **       other windows get a shot at determining the cursor.
  813. **
  814. ** Setting the cursor to the correct cursor isn't as easy as you would expect.
  815. ** DTS.Lib..framework uses the global gCursorPtr as the reference to the cursor.  This is
  816. ** fine if the cursor is pointer-based, but if the cursor is resource-based, it is a bit
  817. ** more of a problem.  What you will need to do is to call DoSetResCursor() to make the
  818. ** resource cursor pointer-based.  DoSetResCursor() will set gCursorPtr to nil, and it
  819. ** also returns the pointer to the permanent copy of the cursor resource.  Just set gCursorPtr
  820. ** to the return result of DoSetResCursor(), and you will be set. */
  821.  
  822. Boolean    WindowCursor(FileRecHndl frHndl, WindowPtr window, Point globalPt)
  823. {
  824.     WindowPtr        oldPort;
  825.     RgnHandle        contRgn;
  826.     Rect            rr, teViewRct, contRct;
  827.     TEHandle        teHndl;
  828.     ControlHandle    viewCtl;
  829.     Point            contOrg;
  830.     CTEDataHndl        teData;
  831.     short            mode;
  832.  
  833.     if (!window) {
  834.         SetCursor(gCursorPtr = &qd.arrow);
  835.         return(true);
  836.     }
  837.  
  838.     oldPort = SetFilePort(frHndl);
  839.     window = (*frHndl)->fileState.window;
  840.  
  841.     GetContentOrigin(window, &contOrg);
  842.     SetOrigin(contOrg.h, contOrg.v);        /* Scroll position of window. */
  843.  
  844.     GetContentRect(window, &contRct);
  845.         /* This returns the content portion of the window in local coordinates,
  846.         ** less document scrollbar and sidebar areas. */
  847.  
  848.     contRgn = NewRgn();
  849.     for (viewCtl = nil; ((viewCtl = CTENext(window, &teHndl, viewCtl, 1, false)) != nil);) {
  850.         teViewRct = (*teHndl)->viewRect;
  851.         SectRect(&teViewRct, &contRct, &rr);
  852.         LocalToGlobalRect(&rr);
  853.         if ((*viewCtl)->contrlVis) {
  854.             if (!(*viewCtl)->contrlHilite) {
  855.                 if (!CTEReadOnly(teHndl)) {
  856.                     RectRgn(contRgn, &rr);
  857.                     teData = (CTEDataHndl)(*viewCtl)->contrlData;
  858.                     mode   = (*teData)->mode;
  859.                     if ((mode & cteActive) || (!(mode & cteTwoStep))) {
  860.                         if (PtInRect(globalPt, &rr)) {
  861.                             gCursorPtr = DoSetResCursor(iBeamCursor);
  862.                             SectRgn(gCursorRgn, contRgn, gCursorRgn);
  863.                             DisposeRgn(contRgn);
  864.                             SetPort(oldPort);
  865.                             return(true);
  866.                         }
  867.                     }
  868.                     DiffRgn(gCursorRgn, contRgn, gCursorRgn);
  869.                 }
  870.             }
  871.         }
  872.     }
  873.     SetCursor(gCursorPtr = &qd.arrow);
  874.     DisposeRgn(contRgn);
  875.     return(true);
  876. }
  877.  
  878.  
  879. /*****************************************************************************/
  880.  
  881.  
  882.  
  883. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  884.  
  885. /* After the DTS.Lib framework disposes of a window, it calls here.  This is
  886. ** to give the application a chance to do any additional tasks related to
  887. ** a window closing.  DTS.StyleChat doesn't have anything else extra to do. */
  888.  
  889. void    WindowGoneFixup(WindowPtr window)
  890. {
  891. #ifndef __MWERKS__
  892. #pragma unused (window)
  893. #endif
  894. }
  895.  
  896.  
  897.  
  898. /*****************************************************************************/
  899.  
  900.  
  901.  
  902. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  903.  
  904. /* The reverse function of ReadDocument. */
  905.  
  906. OSErr    WriteDocument(FileRecHndl frHndl)
  907. {
  908.     return(DefaultWriteDocument(frHndl));
  909. }
  910.  
  911.  
  912.  
  913. /*****************************************************************************/
  914.  
  915.  
  916.  
  917. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  918.  
  919. Boolean    AdjustMenuItems(WindowPtr window, short menuID)
  920. {
  921.     Boolean        redrawMenuBar;
  922.     MenuHandle    menu;
  923.  
  924.     redrawMenuBar = false;
  925.  
  926.     switch (menuID) {
  927.         case mFile:
  928.             redrawMenuBar = DoAdjustFileMenu(window);
  929.             break;
  930.         case mEdit:
  931.             redrawMenuBar = DoAdjustEditMenu(window);
  932.             break;
  933.         default:
  934.             menu = GetMenuHandle(menuID);
  935.             if (menu)
  936.                 (*menu)->enableFlags |= 0xFFFFFFFEL;
  937.             break;
  938.     }
  939.  
  940.     return(redrawMenuBar);
  941. }
  942.  
  943.  
  944.  
  945. /*****************************************************************************/
  946.  
  947.  
  948.  
  949. /* •• You don't call this.  DTS.Lib..framework does for appropriate document type(s). •• */
  950.  
  951. Boolean    DoMenuItem(WindowPtr window, short menuID, short menuItem)
  952. {
  953. #ifndef __MWERKS__
  954. #pragma unused (window)
  955. #endif
  956.  
  957.     return(DoMenuCommand(menuID, menuItem));
  958. }
  959.  
  960.  
  961.  
  962. /*****************************************************************************/
  963. /*****************************************************************************/
  964. /*****************************************************************************/
  965.  
  966.  
  967.  
  968. static void    MyFindText(long *offset)
  969. {
  970.     long    ll;
  971.     char    c1, c2;
  972.  
  973.     if (gNoReplace) {
  974.         *offset = gLen;
  975.         return;
  976.     }
  977.  
  978.     for (;*offset < gLen; ++*offset) {
  979.         c1 = gText[*offset];    if ((c1 >= 'a') && (c1 <= 'z')) c1 -= 32;
  980.         c2 = gFText[0];            if ((c2 >= 'a') && (c2 <= 'z')) c2 -= 32;
  981.         if (c1 == c2) {
  982.             if (gLen - *offset < gFLen) {
  983.                 *offset = gLen;
  984.                 return;
  985.             };
  986.  
  987.             for (ll = 1; ll < gFLen; ++ll) {
  988.                 c1 = gText[*offset + ll];    if ((c1 >= 'a') && (c1 <= 'z')) c1 -= 32;
  989.                 c2 = gFText[ll];            if ((c2 >= 'a') && (c2 <= 'z')) c2 -= 32;
  990.                 if (c1 != c2) break;
  991.             }
  992.             if (ll == gFLen) return;
  993.         }
  994.     }
  995. }
  996.  
  997.  
  998.  
  999. /*****************************************************************************/
  1000.  
  1001.  
  1002.  
  1003. static void    MyReplaceText(long *offset)
  1004. {
  1005.     long    i;
  1006.     char    c1;
  1007.     Boolean    upperCase, lowerCase;
  1008.  
  1009.     upperCase = lowerCase = true;
  1010.     for (i = 0; i < gFLen; ++i) {
  1011.         c1 = gText[*offset + i];
  1012.         if ((c1 >= 'a') && (c1 <= 'z')) upperCase = false;
  1013.         if ((c1 >= 'A') && (c1 <= 'Z')) lowerCase = false;
  1014.     }
  1015.  
  1016.     BlockMove(
  1017.               gText + *offset + gFLen,
  1018.               gText + *offset + gFLen + (gRLen - gFLen),
  1019.               gLen - (*offset + gFLen)
  1020.     );
  1021.  
  1022.     BlockMove(gRText, gText + *offset, gRLen);
  1023.     if (upperCase) {
  1024.         for (i = 0; i < gRLen; ++i) {
  1025.             c1 = gText[*offset + i];
  1026.             if ((c1 >= 'a') && (c1 <= 'z')) gText[*offset + i] -= 32;
  1027.         }
  1028.     }
  1029.     if (lowerCase) {
  1030.         for (i = 0; i < gRLen; ++i) {
  1031.             c1 = gText[*offset + i];
  1032.             if ((c1 >= 'A') && (c1 <= 'Z')) gText[*offset + i] += 32;
  1033.         }
  1034.     }
  1035.  
  1036.     *offset += gRLen;
  1037.     gLen    += (gRLen - gFLen);
  1038. }
  1039.  
  1040.  
  1041.  
  1042. /*****************************************************************************/
  1043.  
  1044.  
  1045.  
  1046. static Boolean    UpdateString(StringPtr s, StringPtr fs, StringPtr rs);
  1047. static Boolean    UpdateString(StringPtr s, StringPtr fs, StringPtr rs)
  1048. {
  1049.     Str255    scmp;
  1050.     short    dd, i;
  1051.     Boolean    update;
  1052.  
  1053.     if (!fs[0]) return(false);
  1054.  
  1055.     update = false;
  1056.     for (i = s[0] - fs[0] + 1; i > 0; --i) {
  1057.         if (s[i] == fs[1]) {
  1058.             BlockMove( (s + i), (scmp + 1), (scmp[0] = fs[0]) );
  1059.             if (!pcmp(scmp, fs)) {
  1060.                 update = true;
  1061.                 dd = (rs[0] - fs[0]);
  1062.                 BlockMove( (s + i + fs[0]),
  1063.                            (s + i + fs[0] + dd),
  1064.                            (s[0] - i + 1)
  1065.                 );
  1066.                 BlockMove( (rs + 1),
  1067.                            (s + i),
  1068.                            (rs[0])
  1069.                 );
  1070.                 s[0] += dd;
  1071.             }
  1072.         } 
  1073.     }
  1074.  
  1075.     return(update);
  1076. }
  1077.  
  1078.  
  1079.  
  1080. /*****************************************************************************/
  1081.  
  1082.  
  1083.  
  1084. static Boolean    UpdateHandle(Handle h, StringPtr fs, StringPtr rs, Boolean resize);
  1085. static Boolean    UpdateHandle(Handle h, StringPtr fs, StringPtr rs, Boolean resize)
  1086. {
  1087.     Str255    scmp;
  1088.     long    dd, i, hl, fl, rl;
  1089.     Boolean    update;
  1090.  
  1091.     if (!fs[0]) return(false);
  1092.  
  1093.     update = false;
  1094.     hl = GetHandleSize(h);
  1095.     fl = fs[0] + 1;
  1096.     rl = rs[0] + 1;
  1097.     for (i = hl - fl; i >= 0; --i) {
  1098.         if ((*h)[i + 1] == fs[1]) {
  1099.             BlockMove((*h + i), scmp, fl);
  1100.             if (!pcmp(scmp, fs)) {
  1101.                 update = true;
  1102.                 dd = (rl - fl);
  1103.                 if (resize)
  1104.                     if (dd > 0)
  1105.                         SetHandleSize(h, hl + dd);
  1106.                 if (resize)
  1107.                     BlockMove( (*h + i + fl), (*h + i + fl + dd), (hl - i - fl) );
  1108.                 BlockMove(rs, *h + i, rl);
  1109.                 if (resize)
  1110.                     if (dd < 0)
  1111.                         SetHandleSize(h, hl + dd);
  1112.                 hl += dd;
  1113.             }
  1114.         } 
  1115.     }
  1116.  
  1117.     return(update);
  1118. }
  1119.  
  1120.  
  1121.  
  1122. /*****************************************************************************/
  1123.  
  1124.  
  1125.  
  1126. static void    FixNMAPs(StringPtr str1, StringPtr str2)
  1127. {
  1128.     OSType    rt, sft;
  1129.     short    rn, sz, phz, keyListLen, keyListTyp, valueListLen, ii;
  1130.     OSType    oo;
  1131.     Handle    hh, hr;
  1132.     Ptr        hrp, hhp;
  1133.     Str255    pstr;
  1134.     Boolean    update;
  1135.  
  1136.     if (gNoReplace) return;
  1137.  
  1138.     update = false;
  1139.     for (rt = 'NMAP'; rt <= 'nmap'; rt += ('nmap' - 'NMAP')) {
  1140.  
  1141.         for (rn = Count1Resources(rt); rn; --rn) {
  1142.  
  1143.             hr = Get1IndResource(rt, rn);
  1144.             HLock(hr);
  1145.             hrp = *hr;
  1146.  
  1147.             hh = NewHandle(4096);
  1148.             HLock(hh);
  1149.             hhp = *hh;
  1150.  
  1151.             for (phz = 0; phz != -1;) {
  1152.                 sz = hrp - *hr;
  1153.                 if (sz >= GetHandleSize(hr)) break;
  1154.                 switch (phz) {
  1155.                     case 0:
  1156.                     case 2:
  1157.                     case 20:
  1158.                     case 21:
  1159.                     case 32:
  1160.                     case 33:
  1161.                         BlockMove(hrp, &sz, sizeof(short));
  1162.                         hrp += sizeof(short);
  1163.                         pstr[0] = sz;
  1164.                         BlockMove(hrp, pstr + 1, pstr[0]);
  1165.                         hrp += pstr[0];
  1166.                         if (UpdateString(pstr, str1, str2)) update = true;
  1167.                         *(short *)hhp = pstr[0];
  1168.                         hhp += sizeof(short);
  1169.                         BlockMove(pstr + 1, hhp, pstr[0]);
  1170.                         hhp += pstr[0];
  1171.                         switch (phz) {
  1172.                             case 0:
  1173.                                 phz = 1;
  1174.                                 break;
  1175.                             case 2:
  1176.                                 phz = 3;
  1177.                                 break;
  1178.                             case 20:
  1179.                                 phz = 99;
  1180.                                 break;
  1181.                             case 21:
  1182.                                 phz = 22;
  1183.                                 break;
  1184.                             case 32:
  1185.                                 phz = 33;
  1186.                                 break;
  1187.                             case 33:
  1188.                                 phz = 31;
  1189.                                 break;
  1190.                         }
  1191.                         break;
  1192.                     case 1:
  1193.                         BlockMove(hrp, &keyListLen, sizeof(short));
  1194.                         hrp += sizeof(short);
  1195.                         BlockMove(&keyListLen, hhp, sizeof(short));
  1196.                         hhp += sizeof(short);
  1197.                         phz = 2;
  1198.                         break;
  1199.                     case 3:
  1200.                         BlockMove(hrp, &keyListTyp, sizeof(short));
  1201.                         hrp += sizeof(short);
  1202.                         BlockMove(&keyListTyp, hhp, sizeof(short));
  1203.                         hhp += sizeof(short);
  1204.                         phz = keyListTyp + 3;    // Cases 4-7 handled separately.
  1205.                         break;
  1206.                     case 4:
  1207.                         BlockMove(hrp, &sft, sizeof(OSType));
  1208.                         hrp += sizeof(OSType);
  1209.                         BlockMove(&sft, hhp, sizeof(OSType));
  1210.                         hhp += sizeof(OSType);
  1211.                         phz = 99;                // Continue processing keyList.
  1212.                         break;
  1213.                     case 5:
  1214.                         BlockMove(hrp, &ii, sizeof(short));
  1215.                         hrp += sizeof(short);
  1216.                         BlockMove(&ii, hhp, sizeof(short));
  1217.                         hhp += sizeof(short);
  1218.                         BlockMove(hrp, &ii, sizeof(short));
  1219.                         hrp += sizeof(short);
  1220.                         BlockMove(&ii, hhp, sizeof(short));
  1221.                         hhp += sizeof(short);
  1222.                         phz = 20;                // wstring, followed by processing keyList.
  1223.                         break;
  1224.                     case 6:
  1225.                     case 9:
  1226.                         phz = 20;                // wstring, followed by processing keyList.
  1227.                         break;
  1228.                     case 7:
  1229.                         BlockMove(hrp, &valueListLen, sizeof(short));
  1230.                         hrp += sizeof(short);
  1231.                         BlockMove(&valueListLen, hhp, sizeof(short));
  1232.                         hhp += sizeof(short);
  1233.                         phz = 21;
  1234.                         break;
  1235.                     case 8:
  1236.                         BlockMove(hrp, &valueListLen, sizeof(short));
  1237.                         hrp += sizeof(short);
  1238.                         BlockMove(&valueListLen, hhp, sizeof(short));
  1239.                         hhp += sizeof(short);
  1240.                         phz = 30;
  1241.                         break;
  1242.                     case 22:
  1243.                     case 31:
  1244.                         --phz; // was phz = 21;
  1245.                         if (!(--valueListLen)) phz = 99;
  1246.                         break;
  1247.                     case 30:
  1248.                         BlockMove(hrp, &oo, sizeof(OSType));
  1249.                         hrp += sizeof(OSType);
  1250.                         BlockMove(&oo, hhp, sizeof(OSType));
  1251.                         hhp += sizeof(OSType);
  1252.                         BlockMove(hrp, &oo, sizeof(OSType));
  1253.                         hrp += sizeof(OSType);
  1254.                         BlockMove(&oo, hhp, sizeof(OSType));
  1255.                         hhp += sizeof(OSType);
  1256.                         
  1257.                         // Parse UserString (integer, integer, wstring)
  1258.                         BlockMove(hrp, &ii, sizeof(short));
  1259.                         hrp += sizeof(short);
  1260.                         BlockMove(&ii, hhp, sizeof(short));
  1261.                         hhp += sizeof(short);
  1262.                         BlockMove(hrp, &ii, sizeof(short));
  1263.                         hrp += sizeof(short);
  1264.                         BlockMove(&ii, hhp, sizeof(short));
  1265.                         hhp += sizeof(short);
  1266.  
  1267.                         // Parse first wstring in case 32
  1268.                         
  1269.                         // Parse Category ISOString (wstring) in case 33
  1270.                         
  1271.                         phz = 32;
  1272.                         break;
  1273.                     case 99:
  1274.                         phz = 3;
  1275.                         if (!(--keyListLen)) phz = -1;
  1276.                         break;
  1277.                 }
  1278.             }
  1279.  
  1280.             sz = hhp - *hh;
  1281.             HUnlock(hr);
  1282.             HUnlock(hh);
  1283.             if (update) {
  1284.                 SetHandleSize(hr, sz);
  1285.                 BlockMove(*hh, *hr, sz);
  1286.                 ChangedResource(hr);
  1287.                 WriteResource(hr);
  1288.             }
  1289.             DisposeHandle(hh);
  1290.         }
  1291.     }
  1292. }
  1293.  
  1294.  
  1295.  
  1296. /*****************************************************************************/
  1297.  
  1298.  
  1299.  
  1300. void    UpdateFileName(StringPtr fname, StringPtr oldpname, StringPtr newpname,
  1301.                        StringPtr prefix, StringPtr suffix);
  1302.  
  1303. void    UpdateFileName(StringPtr fname, StringPtr oldpname, StringPtr newpname,
  1304.                        StringPtr prefix, StringPtr suffix)
  1305. {
  1306.     Str255    ofn, nfn;
  1307.     long    offset;
  1308.  
  1309.     BlockMove(fname + 1, gText, (gLen = fname[0]));
  1310.     for (offset = 0;;) {
  1311.         pcpy(ofn, prefix); pcat(ofn, oldpname); pcat(ofn, suffix);
  1312.         pcpy(nfn, prefix); pcat(nfn, newpname); pcat(nfn, suffix);
  1313.         BlockMove(ofn + 1, gFText, (gFLen = ofn[0]));
  1314.         BlockMove(nfn + 1, gRText, (gRLen = nfn[0]));
  1315.         MyFindText(&offset);
  1316.         if (offset >= gLen) break;
  1317.         MyReplaceText(&offset);
  1318.     }
  1319.     BlockMove(gText, fname + 1, (fname[0] = gLen));
  1320. }
  1321.  
  1322. static void    CreatePart(WindowPtr window)
  1323. {
  1324.     ControlHandle    ctl, acc;
  1325.     Rect            arr;
  1326.     Str63            oldPartName, newPartName;
  1327.     Str63            fileName, oldFileName, directoryName, errstr;
  1328.     Str255            pstr, qstr;
  1329.     Str31            oldCreator, newCreator;
  1330.     StringPtr        pp;
  1331.     short            file, refNum, oldRes, os, ns, dd, hs, oo, rn, rr, gl;
  1332.     short            deskVRefNum, vers, ii, len, numViews, ctlref;
  1333.     long            ll, deskDirID;
  1334.     OSErr            err, eee;
  1335.     long            offset, oldoffset, folderDirID, count;
  1336.     FSSpec            fss;
  1337.     Boolean            brk, atg68k, atgppc, atgfat, doit;
  1338.     CInfoPBRec        block;
  1339.     StringHandle    sh;
  1340.     Handle            hh, h2;
  1341.     OSType            ctyp, ttyp, sft, sft2;
  1342.     DInfo            dinfo;
  1343.     FInfo            finfo;
  1344.     Handle            di, fi, aa, date;
  1345.     CInfoPBRec        pb;
  1346.     TreeObjHndl        wfmt, wf;
  1347.  
  1348.     static StandardFileReply    reply;
  1349.     static char                    gt[2048], gft[512], grt[512];
  1350.  
  1351.     gText  = gt;
  1352.     gFText = gft;
  1353.     gRText = grt;
  1354.  
  1355.     sh = GetString(5000);
  1356.  
  1357.     gDataSetBase = 5000;
  1358.     CNum2Ctl(window, kWhichDataSet, &ctl);
  1359.     if (ctl) {
  1360.         ii = GetControlValue(ctl);
  1361.         switch (ii) {
  1362.             case 1:
  1363.                 gDataSetBase = 5000;
  1364.                 break;
  1365.             case 2:
  1366.                 gDataSetBase = 10000;
  1367.                 break;
  1368.             default:
  1369.                 gDataSetBase = 10000 + 1000 * (ii - 2);
  1370.                 break;
  1371.         }
  1372.     }
  1373.  
  1374.     pcpy(newPartName, *sh);
  1375.     newPartName[1] = newPartName[0] - 1;
  1376.     pcpy(oldPartName, newPartName + 1);
  1377.  
  1378.     VisCNum2Ctl(window, kOldClassName, &ctl);
  1379.     if (ctl) pcpy(oldPartName, (*ctl)->contrlTitle);
  1380.  
  1381.     VisCNum2Ctl(window, kNewClassName, &ctl);
  1382.     CTEGetPStr(ctl, newPartName);
  1383.  
  1384.     pcpy(reply.sfFile.name, newPartName);
  1385.     VisCNum2Ctl(window, kNewFolderName, &ctl);
  1386.     if (ctl) pcpy(reply.sfFile.name, (*ctl)->contrlTitle);
  1387.  
  1388.     if (!DisplayPutFile(&reply)) return;
  1389.     fss = reply.sfFile;
  1390.  
  1391.     DoSetCursor(*GetCursor(watchCursor));
  1392.  
  1393.     DoDrawControls(window, false);
  1394.     SetPort(window);
  1395.  
  1396.     err = DirCreate(fss.vRefNum, fss.parID, fss.name, &folderDirID);
  1397. if (err) { pcpy(errstr, "\p### AAA err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1398.     if (err) return;
  1399.  
  1400.     gFSSpec[gResolveIndx = 0].fss = (FSSpec **)NewHandle(sizeof(FSSpec));
  1401.     if (!gFSSpec[gResolveIndx].fss) DebugStr("\p#1: Not enough memory for jack...");
  1402.     BlockMove(&fss, *gFSSpec[gResolveIndx].fss, sizeof(FSSpec));
  1403.     pcpy(gFSSpec[gResolveIndx++].oldName, oldPartName);
  1404.  
  1405.     di = Get1Resource('dINO', gDataSetBase);
  1406.     if (di) {
  1407.         BlockMove(*di, &dinfo, sizeof(DInfo));
  1408.  
  1409.         dinfo.frLocation.h = 0;
  1410.         dinfo.frLocation.v = 0;
  1411.         if (
  1412.             !FindFolder(kOnSystemDisk, kDesktopFolderType,
  1413.                         kDontCreateFolder, &deskVRefNum, &deskDirID)
  1414.         ) {
  1415.             if (deskVRefNum == fss.vRefNum) {
  1416.                 if (deskDirID == fss.parID) {
  1417.                     dinfo.frLocation.h = -30000;
  1418.                     dinfo.frLocation.v = -30000;
  1419.                 }
  1420.             }
  1421.         }
  1422.         SetDInfo(fss.vRefNum, fss.parID, fss.name, &dinfo);
  1423.     }
  1424.  
  1425.     date = Get1Resource('date', gDataSetBase);
  1426.     if (date) {
  1427.         pb.hFileInfo.ioNamePtr   = fss.name;
  1428.         pb.hFileInfo.ioVRefNum   = fss.vRefNum;
  1429.         pb.hFileInfo.ioDirID     = fss.parID;
  1430.         pb.hFileInfo.ioFDirIndex = 0;    /* use ioNamePtr and ioDirID */
  1431.         if (!PBGetCatInfoSync(&pb)) {
  1432.             pb.hFileInfo.ioFlCrDat = ((long *)(*date))[0];
  1433.             pb.hFileInfo.ioFlMdDat = ((long *)(*date))[1];
  1434.             pb.hFileInfo.ioDirID   = fss.parID;
  1435.             PBSetCatInfoSync(&pb);
  1436.         }
  1437.     }
  1438.  
  1439.     fss.parID = folderDirID;    // Now we're inside our new project folder.
  1440.  
  1441.     DisplayControlSet(window, 'DUM1', kwHideAll);
  1442.     CNum2Ctl(window, kAboutCtlArea, &acc);
  1443.     if (acc) {
  1444.         arr = (*acc)->contrlRect;
  1445.         EraseRect(&arr);
  1446.         InvalRect(&arr);
  1447.     }
  1448.     DisplayControlSet(window, 'DUM2', kwShowAll);
  1449.  
  1450.     for (brk = 0, file = gDataSetBase + 1;
  1451.                   file < gDataSetBase + 4999;
  1452.                   file++) {        /* Loop for all files for project. */
  1453.  
  1454.         date = Get1Resource('date', file);
  1455.  
  1456.         sh = GetString(file);
  1457.         if (!sh) break;        // No more files.
  1458.         pcpy(fileName, *sh);
  1459.  
  1460.         if (fileName[1] == ':') {
  1461.             pp = fileName + 1;
  1462.             pp[0] = fileName[0] - 1;
  1463.  
  1464.             block.dirInfo.ioDrParID = fss.parID;
  1465.             for (;;) {
  1466.                 if (!pp[0]) break;
  1467.                 if (pp[1] != ':') break;
  1468.                 pp[1] = pp[0] - 1;
  1469.                 ++pp;
  1470.                 SetMem(&block, 0, sizeof(CInfoPBRec));
  1471.                 block.dirInfo.ioNamePtr   = directoryName;
  1472.                 block.dirInfo.ioDrParID   = fss.parID;
  1473.                 block.dirInfo.ioVRefNum   = fss.vRefNum;
  1474.                 block.dirInfo.ioFDirIndex = -1;
  1475.                 block.dirInfo.ioDrDirID   = block.dirInfo.ioDrParID;
  1476.                 if (PBGetCatInfo(&block, false)) return;
  1477.             }
  1478.             fss.parID = block.dirInfo.ioDrParID;
  1479.  
  1480.             if (pp[0]) {
  1481.                 pcpy(fss.name, pp);
  1482.                 err = DirCreate(fss.vRefNum, fss.parID, pp, &folderDirID);
  1483. if (err) { pcpy(errstr, "\p### BBB err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1484.                 if (err == dupFNErr) {
  1485.                     SysBeep(1);
  1486.                 }
  1487.                 gFSSpec[gResolveIndx].fss = (FSSpec **)NewHandle(sizeof(FSSpec));
  1488.                 if (!gFSSpec[gResolveIndx].fss) DebugStr("\p#2: Not enough memory for jack...");
  1489.                 if (gFSSpec[gResolveIndx].fss) {
  1490.                     BlockMove(&fss, *gFSSpec[gResolveIndx].fss, sizeof(FSSpec));
  1491.                     pcpy(gFSSpec[gResolveIndx++].oldName, fileName);
  1492.                 }
  1493.  
  1494.                 di = Get1Resource('dINO', file);
  1495.                 if (di) {
  1496.                     BlockMove(*di, &dinfo, sizeof(DInfo));
  1497.                     eee = SetDInfo(fss.vRefNum, fss.parID, fss.name, &dinfo);
  1498.                 }
  1499.  
  1500.                 if (date) {
  1501.                     pb.hFileInfo.ioNamePtr   = fss.name;
  1502.                     pb.hFileInfo.ioVRefNum   = fss.vRefNum;
  1503.                     pb.hFileInfo.ioDirID     = fss.parID;
  1504.                     pb.hFileInfo.ioFDirIndex = 0;    /* use ioNamePtr and ioDirID */
  1505.                     if (!PBGetCatInfoSync(&pb)) {
  1506.                         pb.hFileInfo.ioFlCrDat = ((long *)(*date))[0];
  1507.                         pb.hFileInfo.ioFlMdDat = ((long *)(*date))[1];
  1508.                         pb.hFileInfo.ioDirID   = fss.parID;
  1509.                         PBSetCatInfoSync(&pb);
  1510.                     }
  1511.                 }
  1512.  
  1513.                 if (!err) fss.parID = folderDirID;
  1514.             }
  1515.             continue;
  1516.         }
  1517.  
  1518. #if 0
  1519.         gText = gt;
  1520.         UpdateFileName(fileName, oldPartName, newPartName, "\p",   "\p.c");
  1521.         UpdateFileName(fileName, oldPartName, newPartName, "\p",   "\p.cpp");
  1522.         UpdateFileName(fileName, oldPartName, newPartName, "\p",   "\pInit.cpp");
  1523.         UpdateFileName(fileName, oldPartName, newPartName, "\p",   "\p.h");
  1524.         UpdateFileName(fileName, oldPartName, newPartName, "\p",   "\pDef.h");
  1525.         UpdateFileName(fileName, oldPartName, newPartName, "\p",   "\p.r");
  1526.         UpdateFileName(fileName, oldPartName, newPartName, "\p",   "\p.rsrc");
  1527.         UpdateFileName(fileName, oldPartName, newPartName, "\pC",  "\p.c");
  1528.         UpdateFileName(fileName, oldPartName, newPartName, "\pCP", "\p.cpp");
  1529.         UpdateFileName(fileName, oldPartName, newPartName, "\pCP", "\pStubs.cpp");
  1530.  
  1531.         UpdateFileName(fileName, oldPartName, newPartName, "\p", "\p.µ");
  1532.         UpdateFileName(fileName, oldPartName, newPartName, "\p", "\p.buildxhxih");
  1533.         UpdateFileName(fileName, oldPartName, newPartName, "\p", "\p.idl");
  1534.         UpdateFileName(fileName, oldPartName, newPartName, "\p", "\p.xh");
  1535.         UpdateFileName(fileName, oldPartName, newPartName, "\p", "\p.xih");
  1536. //        UpdateFileName(fileName, oldPartName, newPartName, "\p", "\p");
  1537.  
  1538.         for (ii = 6001;; ii += 2) {
  1539.             VisCNum2Ctl(window, ii, &ctl);
  1540.             if (!ctl) break;
  1541.             pcpy(pstr, (*ctl)->contrlTitle);
  1542.             VisCNum2Ctl(window, ii + 1, &ctl);
  1543.             if (!ctl) break;
  1544.             pcpy(qstr, (*ctl)->contrlTitle);
  1545.             if (pstr[0] + qstr[0] > 0)
  1546.                 UpdateFileName(fileName, oldPartName, newPartName, pstr, qstr);
  1547.         }
  1548. #endif
  1549.  
  1550.         pcpy(oldFileName, fileName);
  1551.         gText = gt;
  1552.         BlockMove(fileName + 1, gText, (gLen = fileName[0]));
  1553.         for (offset = 0;;) {
  1554.             BlockMove(oldPartName + 1, gFText, (gFLen = oldPartName[0]));
  1555.             BlockMove(newPartName + 1, gRText, (gRLen = newPartName[0]));
  1556.             MyFindText(&offset);
  1557.             if (offset >= gLen) break;
  1558.             MyReplaceText(&offset);
  1559.         }
  1560.         BlockMove(gText, fileName + 1, (fileName[0] = gLen));
  1561.             /* This is now the name of the file, with HelloPart portion replaced. */
  1562.  
  1563.         CNum2Ctl(window, 201, &ctl);        /* writing to... controls. */
  1564. if (!ctl) DebugStr("\pctl is nil @ A");
  1565.         pcpy(pstr, (*ctl)->contrlTitle);
  1566.         pcat(pstr, fileName);
  1567.         CNum2Ctl(window, 202, &ctl);
  1568. if (!ctl) DebugStr("\pctl is nil @ B");
  1569.         pcat(pstr, (*ctl)->contrlTitle);
  1570.         CNum2Ctl(window, 200, &ctl);
  1571. if (!ctl) DebugStr("\pctl is nil @ C");
  1572.         SetStyledCTitle(ctl, pstr);
  1573.  
  1574.         hh = Get1Resource('cTYP', file);
  1575. if (!hh) DebugStr("\presource not found @ A");
  1576.         BlockMove(*hh, &ctyp, sizeof(OSType));
  1577.         hh = Get1Resource('tTYP', file);
  1578. if (!hh) DebugStr("\presource not found @ B");
  1579.         BlockMove(*hh, &ttyp, sizeof(OSType));
  1580.  
  1581.         pcpy(fss.name, fileName);
  1582.         err = HCreate(fss.vRefNum, fss.parID, fss.name, ctyp, ttyp);
  1583. if (err) { pcpy(errstr, "\p### CCC err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1584.         if (err) {
  1585.             DisplayControlSet(window, 'DUM2', kwHideAll);
  1586.             CNum2Ctl(window, kAboutCtlArea, &acc);
  1587.             if (acc) {
  1588.                 arr = (*acc)->contrlRect;
  1589.                 EraseRect(&arr);
  1590.                 InvalRect(&arr);
  1591.             }
  1592.             DisplayControlSet(window, 'DUM1', kwShowAll);
  1593.             return;
  1594.         }
  1595.  
  1596.         gFSSpec[gResolveIndx].fss = (FSSpec **)NewHandle(sizeof(FSSpec));
  1597.         if (!gFSSpec[gResolveIndx].fss) DebugStr("\p#3: Not enough memory for jack...");
  1598.         if (gFSSpec[gResolveIndx].fss) {
  1599.             BlockMove(&fss, *gFSSpec[gResolveIndx].fss, sizeof(FSSpec));
  1600.             pcpy(gFSSpec[gResolveIndx++].oldName, oldFileName);
  1601.         }
  1602.  
  1603.         fi = Get1Resource('fINO', file);
  1604.         if (fi) {
  1605.             BlockMove(*fi, &finfo, sizeof(FInfo));
  1606.             eee = HSetFInfo(fss.vRefNum, fss.parID, fss.name, &finfo);
  1607.         }
  1608.  
  1609.         err = HOpenDF(fss.vRefNum, fss.parID, fileName, fsRdWrPerm, &refNum);
  1610. if (err) { pcpy(errstr, "\p### DDD err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1611.         if (err) {
  1612. //wrong        FSClose(refNum);
  1613.  
  1614.             CNum2Ctl(window, kAboutCtlArea, &acc);
  1615.             if (acc) {
  1616.                 arr = (*acc)->contrlRect;
  1617.                 EraseRect(&arr);
  1618.                 InvalRect(&arr);
  1619.             }
  1620.             DisplayControlSet(window, 'DUM2', kwHideAll);
  1621.             CNum2Ctl(window, kAboutCtlArea, &acc);
  1622.             if (acc) {
  1623.                 arr = (*acc)->contrlRect;
  1624.                 EraseRect(&arr);
  1625.                 InvalRect(&arr);
  1626.             }
  1627.             DisplayControlSet(window, 'DUM1', kwShowAll);
  1628.             return;
  1629.         }
  1630.  
  1631.         err = SetFPos(refNum, fsFromStart, 0);
  1632. if (err) { pcpy(errstr, "\p### EEE err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1633.         if (err) {
  1634.             FSClose(refNum);
  1635.             DisplayControlSet(window, 'DUM2', kwHideAll);
  1636.             CNum2Ctl(window, kAboutCtlArea, &acc);
  1637.             if (acc) {
  1638.                 arr = (*acc)->contrlRect;
  1639.                 EraseRect(&arr);
  1640.                 InvalRect(&arr);
  1641.             }
  1642.             DisplayControlSet(window, 'DUM1', kwShowAll);
  1643.             return;
  1644.         }
  1645.  
  1646.         atg68k = atgppc = atgfat = 0;
  1647.  
  1648.         hh = Get1Resource('dFRK', file);
  1649. if (!hh) {
  1650.     err = ResError();
  1651.     DebugStr("\presource not found @ C");
  1652. }
  1653.  
  1654.         DetachResource(hh);
  1655.         gLen = GetHandleSize(hh);
  1656.         SetHandleSize(hh, gLen + 0X20000L);        // Give the buffer some slop, please
  1657. err = MemError();
  1658. if (err) {
  1659.     DebugStr("\pmem error @ C2");
  1660. }
  1661.         HLock(hh);
  1662.  
  1663.         gText = *hh;    // Careful -- "static" work area pointing to a handle that will go away.
  1664.  
  1665.         if ((ttyp == 'MMPR') || (ttyp == 'PRØJ')) {                    // Metrowerks.
  1666.  
  1667.             pcpy(pstr, oldPartName); pcat(pstr, "\p.68k copy");        // AppsToGo
  1668.             pcpy(qstr, newPartName); pcat(qstr, "\p.68k copy");
  1669.             atg68k = UpdateHandle(hh, pstr, qstr, false);
  1670.  
  1671.             pcpy(pstr, oldPartName); pcat(pstr, "\p.PPC copy");        // AppsToGo
  1672.             pcpy(qstr, newPartName); pcat(qstr, "\p.PPC copy");
  1673.             atgppc = UpdateHandle(hh, pstr, qstr, false);
  1674.  
  1675.             pcpy(pstr, oldPartName); pcat(pstr, "\p.68k");            // AppsToGo FAT build.
  1676.             pcpy(qstr, newPartName); pcat(qstr, "\p.68k");
  1677.             atgfat = UpdateHandle(hh, pstr, qstr, false);
  1678.  
  1679.             pcpy(pstr, oldPartName); pcat(pstr, "\p.c");            // OpenDoc.
  1680.             pcpy(qstr, newPartName); pcat(qstr, "\p.c");
  1681.             UpdateHandle(hh, pstr, qstr, false);
  1682.             pcpy(pstr, oldPartName); pcat(pstr, "\p.cpp");
  1683.             pcpy(qstr, newPartName); pcat(qstr, "\p.cpp");
  1684.             UpdateHandle(hh, pstr, qstr, false);
  1685.             pcpy(pstr, oldPartName); pcat(pstr, "\pInit.cpp");
  1686.             pcpy(qstr, newPartName); pcat(qstr, "\pInit.cpp");
  1687.             UpdateHandle(hh, pstr, qstr, false);
  1688.             pcpy(pstr, oldPartName); pcat(pstr, "\p.h");
  1689.             pcpy(qstr, newPartName); pcat(qstr, "\p.h");
  1690.             UpdateHandle(hh, pstr, qstr, false);
  1691.             pcpy(pstr, oldPartName); pcat(pstr, "\pDef.h");
  1692.             pcpy(qstr, newPartName); pcat(qstr, "\pDef.h");
  1693.             UpdateHandle(hh, pstr, qstr, false);
  1694.             pcpy(pstr, oldPartName); pcat(pstr, "\p.r");
  1695.             pcpy(qstr, newPartName); pcat(qstr, "\p.r");
  1696.             UpdateHandle(hh, pstr, qstr, false);
  1697.             pcpy(pstr, oldPartName); pcat(pstr, "\p.rsrc");
  1698.             pcpy(qstr, newPartName); pcat(qstr, "\p.rsrc");
  1699.             UpdateHandle(hh, pstr, qstr, false);
  1700.             pcpy(pstr, "\pC"); pcat(pstr, oldPartName); pcat(pstr, "\p.c");
  1701.             pcpy(qstr, "\pC"); pcat(qstr, newPartName); pcat(qstr, "\p.c");
  1702.             UpdateHandle(hh, pstr, qstr, false);
  1703.             pcpy(pstr, "\pCP"); pcat(pstr, oldPartName); pcat(pstr, "\p.cpp");
  1704.             pcpy(qstr, "\pCP"); pcat(qstr, newPartName); pcat(qstr, "\p.cpp");
  1705.             UpdateHandle(hh, pstr, qstr, false);
  1706.             pcpy(pstr, "\pCP"); pcat(pstr, oldPartName); pcat(pstr, "\pStubs.cpp");
  1707.             pcpy(qstr, "\pCP"); pcat(qstr, newPartName); pcat(qstr, "\pStubs.cpp");
  1708.             UpdateHandle(hh, pstr, qstr, false);
  1709.  
  1710.             for (ii = 6001;; ii += 2) {
  1711.                 VisCNum2Ctl(window, ii, &ctl);
  1712.                 if (!ctl) break;
  1713.                 len = (*ctl)->contrlTitle[0];
  1714.                 pcpy(pstr, (*ctl)->contrlTitle); pcat(pstr, oldPartName);
  1715.                 pcpy(qstr, (*ctl)->contrlTitle); pcat(qstr, newPartName);
  1716.                 VisCNum2Ctl(window, ii + 1, &ctl);
  1717.                 if (!ctl) break;
  1718.                 pcat(pstr, (*ctl)->contrlTitle);
  1719.                 pcat(qstr, (*ctl)->contrlTitle);
  1720.                 len += (*ctl)->contrlTitle[0];
  1721.                 if (len) UpdateHandle(hh, pstr, qstr, false);
  1722.             }
  1723.         }
  1724.  
  1725.         if (ttyp == 'TEXT') {
  1726.             for (offset = 0;;) {
  1727.                 BlockMove(oldPartName + 1, gFText, (gFLen = oldPartName[0]));
  1728.                 BlockMove(newPartName + 1, gRText, (gRLen = newPartName[0]));
  1729.                 MyFindText(&offset);
  1730.                 if (offset >= gLen) break;
  1731.                 MyReplaceText(&offset);
  1732.             }
  1733.             VisCNum2Ctl(window, kNewCompanyName, &ctl);
  1734.             if (ctl) {
  1735.                 CTEGetPStr(ctl, qstr);
  1736.                 VisCNum2Ctl(window, kOldCompanyName, &ctl);
  1737.                 if (ctl) {
  1738.                     for (offset = 0;;) {
  1739.                         pcpy(pstr, (*ctl)->contrlTitle);
  1740.                         BlockMove(pstr + 1, gFText, (gFLen = pstr[0]));
  1741.                         BlockMove(qstr + 1, gRText, (gRLen = qstr[0]));
  1742.                         MyFindText(&offset);
  1743.                         if (offset >= gLen) break;
  1744.                         MyReplaceText(&offset);
  1745.                     }
  1746.                 }
  1747.             }
  1748.  
  1749.             oldCreator[0] = 0;
  1750.             newCreator[0] = 0;
  1751.             VisCNum2Ctl(window, kAppWannabeCreator, &ctl);
  1752.             if (ctl) {
  1753.                 CTEGetPStr(ctl, pstr);
  1754.                 pcpy(newCreator, pstr);
  1755.                 pcpy(qstr, "\p'");
  1756.                 pcat(qstr, pstr);
  1757.                 pcat(qstr, "\p'");
  1758.                 VisCNum2Ctl(window, kOldAppWannabeCreator, &ctl);
  1759.                 if (ctl) {
  1760.                     pcpy(pstr, (*ctl)->contrlTitle);
  1761.                     oldCreator[0] = sizeof(OSType);
  1762.                     BlockMove(pstr + 2, oldCreator + 1, sizeof(OSType));
  1763.                     for (offset = 0;;) {
  1764.                         BlockMove(pstr + 1, gFText, (gFLen = pstr[0]));
  1765.                         BlockMove(qstr + 1, gRText, (gRLen = qstr[0]));
  1766.                         MyFindText(&offset);
  1767.                         if (offset >= gLen) break;
  1768.                         oldoffset = offset;
  1769.                         MyReplaceText(&offset);
  1770.                         BlockMove(gRText, gText + oldoffset, gRLen);    // Use source case.
  1771.                     }
  1772.                 }
  1773.             }
  1774.             VisCNum2Ctl(window, kAppWannabeDefDoc, &ctl);
  1775.             if (ctl) {
  1776.                 CTEGetPStr(ctl, pstr);
  1777.                 pcpy(qstr, "\p'");
  1778.                 pcat(qstr, pstr);
  1779.                 pcat(qstr, "\p'");
  1780.                 VisCNum2Ctl(window, kOldAppWannabeDefDoc, &ctl);
  1781.                 if (ctl) {
  1782.                     pcpy(pstr, (*ctl)->contrlTitle);
  1783.                     for (offset = 0;;) {
  1784.                         BlockMove(pstr + 1, gFText, (gFLen = pstr[0]));
  1785.                         BlockMove(qstr + 1, gRText, (gRLen = qstr[0]));
  1786.                         MyFindText(&offset);
  1787.                         if (offset >= gLen) break;
  1788.                         oldoffset = offset;
  1789.                         MyReplaceText(&offset);
  1790.                         BlockMove(gRText, gText + oldoffset, gRLen);    // Use source case.
  1791.                     }
  1792.                 }
  1793.             }
  1794.         }
  1795.  
  1796.         count = gLen;
  1797.         err   = FSWrite(refNum, &count, gText);
  1798. if (err) { pcpy(errstr, "\p### FFF err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1799.  
  1800.         DisposeHandle(hh);
  1801.         gText = gt;                // gText is safe again -- done being careful.
  1802.  
  1803.         FSClose(refNum);        // Done with data fork.
  1804.  
  1805.         refNum = kInvalRefNum;
  1806.         HCreateResFile(fss.vRefNum, fss.parID, fileName);
  1807.         err = ResError();
  1808. if (err) { pcpy(errstr, "\p### GGG err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1809.         if (!err) {
  1810.             refNum = HOpenResFile(fss.vRefNum, fss.parID, fileName, fsRdWrPerm);
  1811.             err    = ResError();
  1812.             if (!err) CloseResFile(refNum);        // We don't want to deal with it as a resource fork.
  1813. if (err)
  1814. { pcpy(errstr, fileName); pcat(errstr, "\p### HHH err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1815.         }
  1816.  
  1817. if (err) { pcpy(errstr, "\p### III err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1818.         if (!err) {
  1819.             hh = Get1Resource('rFRK', file);
  1820. if (!hh) DebugStr("\presource not found @ D");
  1821.             HLock(hh);
  1822.             err = HOpenRF(fss.vRefNum, fss.parID, fileName, fsRdWrPerm, &refNum);
  1823. //            SetFPos(refNum, fsFromStart, 0);
  1824. if (err) { pcpy(errstr, "\p### JJJ err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1825.             if (!err) {
  1826.                 count = GetHandleSize(hh);
  1827.                 err   = FSWrite(refNum, &count, *hh);
  1828. if (err) { pcpy(errstr, "\p### KKK err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1829.                 SetEOF(refNum, count);
  1830.                 FSClose(refNum);
  1831.             }
  1832.             DetachResource(hh);
  1833.             DisposeHandle(hh);
  1834.         }
  1835.  
  1836. if (err) { pcpy(errstr, "\p### LLL err = $"); pcathex(errstr, err); DebugStr(errstr); }
  1837.         if (!err) {
  1838.             oldRes = CurResFile();
  1839.             refNum = HOpenResFile(fss.vRefNum, fss.parID, fileName, fsRdWrPerm);
  1840.             UseResFile(refNum);
  1841.  
  1842.             if (finfo.fdFlags & kIsAlias) {
  1843.                 aa = Get1Resource('alis', 0);
  1844.                 if (aa) {
  1845.                     DetachResource(aa);
  1846.                     gAlias[gResolveIndx - 1] = (AliasHandle)aa;
  1847.                 }
  1848.             }
  1849.  
  1850.             VisCNum2Ctl(window, kOldCompanyName, &ctl);
  1851.             if (ctl) {
  1852.                 pcpy(pstr, (*ctl)->contrlTitle);
  1853.                 VisCNum2Ctl(window, kNewCompanyName, &ctl);
  1854.                 if (ctl) {
  1855.                     CTEGetPStr(ctl, qstr);
  1856.                     pcat(pstr, "\p:");
  1857.                     pcat(qstr, "\p:");
  1858.                     FixNMAPs(pstr, qstr);
  1859.                     FixNMAPs(oldPartName, newPartName);
  1860.                 }
  1861.             }
  1862.  
  1863.  
  1864.             VisCNum2Ctl(window, kNewCompanyName, &ctl);
  1865.             if (ctl) {
  1866.                 if ((ttyp == 'rsrc') || (ttyp == 'RSRC')) {
  1867.                     if ((ctyp == 'RSED') || (ctyp == 'Doug')) {
  1868.                         hh = Get1Resource('cfrg', 0);
  1869.                         if ((!gNoReplace) && (hh)) {
  1870.                             hs = GetHandleSize(hh);
  1871.     
  1872.                             pcpy(pstr, (StringPtr)((*hh) + 0x20 + 0x2A));
  1873.                             pcpy(qstr, pstr);
  1874.  
  1875.  
  1876.  
  1877. gFLen = gRLen = 0;
  1878. BlockMove(qstr + 1, gText, (gLen = qstr[0]));
  1879. VisCNum2Ctl(window, kOldCompanyName, &ctl);
  1880. if (ctl) {
  1881.     pcpy(qstr, (*ctl)->contrlTitle);
  1882.     BlockMove(qstr + 1, gFText, (gFLen = qstr[0]));
  1883. }
  1884. VisCNum2Ctl(window, kNewCompanyName, &ctl);
  1885. if (ctl) {
  1886.     CTEGetPStr(ctl, qstr);
  1887.     BlockMove(qstr + 1, gRText, (gRLen = qstr[0]));
  1888. }
  1889. if ((gFLen) && (gRLen)) {
  1890.     for (offset = 0;;) {
  1891.         MyFindText(&offset);
  1892.         if (offset >= gLen) break;
  1893.         MyReplaceText(&offset);
  1894.     }
  1895.     for (offset = 0;;) {
  1896.         BlockMove(oldPartName + 1, gFText, (gFLen = oldPartName[0]));
  1897.         BlockMove(newPartName + 1, gRText, (gRLen = newPartName[0]));
  1898.         MyFindText(&offset);
  1899.         if (offset >= gLen) break;
  1900.         MyReplaceText(&offset);
  1901.     }
  1902.     BlockMove(gText, qstr + 1, (qstr[0] = gLen));
  1903. }
  1904.  
  1905.                             if (pcmp(pstr, qstr)) {
  1906.                                 SetHandleSize(hh, hs + 0x1000);
  1907.     
  1908. //                                VisCNum2Ctl(window, kNewCompanyName, &ctl);
  1909. //                                CTEGetPStr(ctl, qstr);
  1910. //                                pcatchr(qstr, ':', 2);
  1911. //                                pcat(qstr, newPartName);
  1912.  
  1913.                                 os = (0x20 + 0x2A + pstr[0] + 1 + 0x03) & 0xFFFC;
  1914.                                 ns = (0x20 + 0x2A + qstr[0] + 1 + 0x03) & 0xFFFC;
  1915.                                 dd = ns - os;
  1916.                                 BlockMove(*hh + os, *hh + ns, hs);
  1917.                                 pcpy((StringPtr)((*hh) + 0x20 + 0x2A), qstr);
  1918.                                 *(short *)((*hh) + 0x20 + 0x28) = ns - 0x20;
  1919.                                 hs += dd;        // Guaranteed to still be long-aligned, since dd is...
  1920.     
  1921.                                 pcpy(pstr, (StringPtr)((*hh) + ns + 0x2A));
  1922.                                 pcpy(qstr, pstr);
  1923.  
  1924. BlockMove(qstr + 1, gText, (gLen = qstr[0]));
  1925. for (offset = 0;;) {
  1926.     BlockMove(oldPartName + 1, gFText, (gFLen = oldPartName[0]));
  1927.     BlockMove(newPartName + 1, gRText, (gRLen = newPartName[0]));
  1928.     MyFindText(&offset);
  1929.     if (offset >= gLen) break;
  1930.     MyReplaceText(&offset);
  1931. }
  1932. BlockMove(gText, qstr + 1, (qstr[0] = gLen));
  1933.  
  1934.  
  1935.                                 oo =  ns + 0x2A;
  1936.                                 os = (oo + pstr[0] + 1 + 0x03) & 0xFFFC;
  1937.                                 ns = (oo + qstr[0] + 1 + 0x03) & 0xFFFC;
  1938.                                 pcpy((StringPtr)((*hh) + oo), qstr);
  1939.                                 *(short *)((*hh) + oo - sizeof(short)) = ns - oo + 0x2A;
  1940.     
  1941.                                 SetHandleSize(hh, ns);
  1942.                                 ChangedResource(hh);
  1943.                                 WriteResource(hh);
  1944.                             }
  1945.                         }
  1946.                     }
  1947.                 }
  1948.             }
  1949.  
  1950.             if (ttyp == 'MMPR') {        // Update Metrowerks PPC project library name / creator.
  1951.                 if (ctyp == 'MPCC') {
  1952.                     hh = Get1Resource('pVer', 0);
  1953.                     if ((!gNoReplace) && (hh)) {
  1954.                         if (GetHandleSize(hh) == 2) {
  1955.                             vers = **(short **)hh;
  1956.                             if ((vers == 2) || (vers == 3)) {
  1957.                                 hh = Get1Resource('pref', 805);
  1958.                                 if (hh) {
  1959.                                     BlockMove(*hh + 4, qstr, GetHandleSize(hh) - 4);
  1960.                                     pstr[0] = qstr[0];
  1961.                                     for (;;) {
  1962.                                         if (!qstr[0])             break;
  1963.                                         if (qstr[qstr[0]] == ':') break;
  1964.                                         qstr[0]--;
  1965.                                     }
  1966.                                     pstr[0] -= qstr[0];
  1967.                                     BlockMove(qstr + 1 + qstr[0], pstr + 1, pstr[0]);
  1968.                                     UpdateFileName(pstr, oldPartName, newPartName, "\p", "\p");
  1969.                                     pcat(qstr, pstr);
  1970.  
  1971. //                                    pcat(qstr, newPartName);
  1972. //                                    if ((atgppc) && (!atgfat)) pcat(qstr, "\p.PPC");
  1973. //                                    if (atgfat)                pcat(qstr, "\p.FAT");
  1974.  
  1975.                                     BlockMove(qstr, *hh + 4, qstr[0] + 1);
  1976.                                     VisCNum2Ctl(window, kAppWannabeCreator, &ctl);
  1977.                                     if (ctl) {
  1978.                                         CTEGetPStr(ctl, qstr);
  1979.                                         BlockMove(qstr + 1, *hh + 0x24, sizeof(OSType));
  1980.                                     }
  1981.                                     ChangedResource(hh);
  1982.                                     WriteResource(hh);
  1983.                                 }
  1984.                             }
  1985.                         }
  1986.                     }
  1987.                 }
  1988.             }
  1989.  
  1990.  
  1991. if (ttyp == 'MMPR') {        // Update Metrowerks PPC PEF name.
  1992.     if (ctyp == 'MPCC') {
  1993.         hh = Get1Resource('pVer', 0);
  1994.         if ((!gNoReplace) && (hh)) {
  1995.             if (GetHandleSize(hh) == 2) {
  1996.                 vers = **(short **)hh;
  1997.                 if ((vers == 2) || (vers == 3)) {
  1998.                     hh = Get1Resource('pref', 807);
  1999.                     if (hh) {
  2000.                         BlockMove(*hh + 18, qstr, GetHandleSize(hh) - 18);
  2001.                         pstr[0] = qstr[0];
  2002.                         for (;;) {
  2003.                             if (!qstr[0])             break;
  2004.                             if (qstr[qstr[0]] == ':') break;
  2005.                             qstr[0]--;
  2006.                         }
  2007.                         pstr[0] -= qstr[0];
  2008.                         BlockMove(qstr + 1 + qstr[0], pstr + 1, pstr[0]);
  2009.                         UpdateFileName(pstr, oldPartName, newPartName, "\p", "\p");
  2010.                         pcat(qstr, pstr);
  2011.  
  2012.                         BlockMove(qstr, *hh + 18, qstr[0] + 1);
  2013.                         ChangedResource(hh);
  2014.                         WriteResource(hh);
  2015.                     }
  2016.                 }
  2017.             }
  2018.         }
  2019.     }
  2020. }
  2021.  
  2022.             CNum2Ctl(window, kOpenDoc, &ctl);
  2023.             if (ctl) {                            // This code is just for OpenDoc support.
  2024.                 if (ttyp == 'MMPR') {            // Update Metrowerks PPC project link names.
  2025.                     if (ctyp == 'MPCC') {
  2026.                         hh = Get1Resource('pVer', 0);
  2027.                         if ((!gNoReplace) && (hh)) {
  2028.                             if (GetHandleSize(hh) == 2) {
  2029.                                 vers = **(short **)hh;
  2030.                                 if ((vers == 2) || (vers == 3)) {
  2031.                                     hh = Get1Resource('pref', 804);
  2032.                                     if (hh) {
  2033.                                         pcpy(qstr, newPartName);
  2034.                                         pcat(qstr, "\pCFMInit\0");
  2035.                                         BlockMove(qstr + 1, *hh + 0x04, qstr[0] + 1);
  2036.                                         pcpy(qstr, newPartName);
  2037.                                         pcat(qstr, "\pSOMInit\0");
  2038.                                         BlockMove(qstr + 1, *hh + 0x44, qstr[0] + 1);
  2039.                                         ChangedResource(hh);
  2040.                                         WriteResource(hh);
  2041.                                     }
  2042.                                 }
  2043.                             }
  2044.                         }
  2045.                     }
  2046.                 }
  2047.             }
  2048.  
  2049.             if (ttyp == 'MMPR') {        // Update Metrowerks 68k project library name / creator.
  2050.                 if (ctyp == 'MMCC') {
  2051.                     hh = Get1Resource('pVer', 0);
  2052.                     if ((!gNoReplace) && (hh)) {
  2053.                         if (GetHandleSize(hh) == 2) {
  2054.                             vers = **(short **)hh;
  2055.                             if ((vers == 2) || (vers == 3)) {
  2056.                                 hh = Get1Resource('pref', 5);
  2057.                                 if (hh) {
  2058.                                     BlockMove(*hh + 4, qstr, GetHandleSize(hh) - 4);
  2059.                                     pstr[0] = qstr[0];
  2060.                                     for (;;) {
  2061.                                         if (!qstr[0])             break;
  2062.                                         if (qstr[qstr[0]] == ':') break;
  2063.                                         qstr[0]--;
  2064.                                     }
  2065.                                     pstr[0] -= qstr[0];
  2066.                                     BlockMove(qstr + 1 + qstr[0], pstr + 1, pstr[0]);
  2067.                                     UpdateFileName(pstr, oldPartName, newPartName, "\p", "\p");
  2068.                                     pcat(qstr, pstr);
  2069.  
  2070. //                                    pcat(qstr, newPartName);
  2071. //                                    if (atg68k) pcat(qstr, "\p.68k");
  2072.                                     BlockMove(qstr, *hh + 4, qstr[0] + 1);
  2073.  
  2074.                                     VisCNum2Ctl(window, kAppWannabeCreator, &ctl);
  2075.                                     if (ctl) {
  2076.                                         CTEGetPStr(ctl, qstr);
  2077.                                         BlockMove(qstr + 1, *hh + 0x44, sizeof(OSType));
  2078.                                     }
  2079.                                     ChangedResource(hh);
  2080.                                     WriteResource(hh);
  2081.                                 }
  2082.                             }
  2083.                         }
  2084.                     }
  2085.                 }
  2086.             }
  2087.  
  2088.             if (ttyp == 'PROJ') {        // Update THINK project library name / creator.
  2089.                 if (ctyp == 'KAHL') {
  2090.                     hh = Get1Resource('KIND', 0);
  2091.                     if ((!gNoReplace) && (hh)) {
  2092.                         BlockMove(newPartName, *hh + 0x10C, newPartName[0] + 1);
  2093.                         VisCNum2Ctl(window, kAppWannabeCreator, &ctl);
  2094.                         if (ctl) {
  2095.                             CTEGetPStr(ctl, qstr);
  2096.                             BlockMove(qstr + 1, *hh + 0x150, sizeof(OSType));
  2097.                         }
  2098.                         ChangedResource(hh);
  2099.                         WriteResource(hh);
  2100.                     }
  2101.                 }
  2102.             }
  2103.  
  2104.             if ((ttyp == 'rsrc') || (ttyp == 'RSRC')) {
  2105.  
  2106.                 if (!gNoReplace) {
  2107.                     VisCNum2Ctl(window, kMacAppViews, &ctl);
  2108.                     if (ctl) {
  2109.                         for (numViews = Count1Resources('View'); numViews; --numViews) {
  2110.                             hh = Get1IndResource('View', numViews);
  2111.                             if (hh) {
  2112.                                 doit = false;
  2113.                                 for (ii = kMacAppViews + 1;; ii += 2) {
  2114.                                     VisCNum2Ctl(window, ii, &ctl);
  2115.                                     if (!ctl) break;
  2116.                                     len = (*ctl)->contrlTitle[0];
  2117.                                     pcpy(pstr, (*ctl)->contrlTitle); pcat(pstr, oldPartName);
  2118.                                     pcpy(qstr, (*ctl)->contrlTitle); pcat(qstr, newPartName);
  2119.                                     VisCNum2Ctl(window, ii + 1, &ctl);
  2120.                                     if (!ctl) break;
  2121.                                     pcat(pstr, (*ctl)->contrlTitle);
  2122.                                     pcat(qstr, (*ctl)->contrlTitle);
  2123.                                     len += (*ctl)->contrlTitle[0];
  2124.                                     if (len) doit |= UpdateHandle(hh, pstr, qstr, true);
  2125.                                 }
  2126.                                 if (doit) {
  2127.                                     ChangedResource(hh);
  2128.                                     WriteResource(hh);
  2129.                                 }
  2130.                             }    
  2131.                         }
  2132.                     }
  2133.                 }
  2134.  
  2135.                 doit = false;
  2136.                 CNum2Ctl(window, kOpenDoc, &ctl);
  2137.                 if (ctl) doit = true;
  2138.                 VisCNum2Ctl(window, kAppWannabeCreator, &ctl);
  2139.                 if (ctl) doit = true;
  2140.                 if (gNoReplace) doit = false;
  2141.  
  2142.                 if (doit) {
  2143.                     for (rr = 0; rr < 2; ++rr) {
  2144.                         switch (rr) {
  2145.                             case 0: sft = 'MENU'; break;
  2146.                             case 1: sft = 'STR#'; break;
  2147.                         }
  2148.                         for (rn = Count1Resources(sft); rn; --rn) {
  2149.                             switch (rr) {
  2150.                                 case 0: oo = 0x0E; break;
  2151.                                 case 1: oo = 0x02; break;
  2152.                             }
  2153.                             hh = Get1IndResource(sft, rn);
  2154.                             if ((!gNoReplace) && (hh)) {
  2155.                                 for (;;) {
  2156.                                     hs = GetHandleSize(hh);
  2157.                                     if (oo >= hs) break;
  2158.                                     pcpy((StringPtr)gText, (StringPtr)((*hh) + oo));
  2159.                                     gLen = gl = (gText[0] + 1);
  2160.                                     for (offset = 0;;) {
  2161.                                         BlockMove(oldPartName + 1, gFText, (gFLen = oldPartName[0]));
  2162.                                         BlockMove(newPartName + 1, gRText, (gRLen = newPartName[0]));
  2163.                                         MyFindText(&offset);
  2164.                                         if (offset >= gLen) break;
  2165.                                         MyReplaceText(&offset);
  2166.                                     }
  2167.                                     gText[0] = gLen - 1;
  2168.                                     SetHandleSize(hh, 0x10000L);
  2169.                                     BlockMove(
  2170.                                         (*hh) + oo + gl,
  2171.                                         (*hh) + oo + gl + (gLen - gl),
  2172.                                         hs
  2173.                                     );
  2174.                                     SetHandleSize(hh, hs + (gLen - gl));
  2175.                                     pcpy((StringPtr)((*hh) + oo), (StringPtr)gText);
  2176.                                     oo += gLen;
  2177.                                 }
  2178.                                 ChangedResource(hh);
  2179.                                 WriteResource(hh);
  2180.                             }
  2181.                         }
  2182.                     }
  2183.                 }
  2184.  
  2185.                 CNum2Ctl(window, kOpenDoc, &ctl);
  2186.                 if (ctl) {
  2187.                     ctlref = GetControlReference(ctl);
  2188.                     if (ctlref) {
  2189.                         hh = Get1Resource('DITL', ctlref);
  2190.                         if ((!gNoReplace) && (hh)) {
  2191.                             pcpy   (pstr, newPartName);
  2192.                             pcatchr(pstr, ' ', 40);
  2193.                             BlockMove(pstr + 1, (*hh) + 0x20, 40);
  2194.                             ChangedResource(hh);
  2195.                             WriteResource(hh);
  2196.                         }
  2197.                     }
  2198.                 }
  2199.  
  2200.                 if (!gNoReplace) {
  2201.                     VisCNum2Ctl(window, kAppWannabeCreator, &ctl);
  2202.  
  2203.                     if (ctl) {                            // This code is just for AppsToGo support.
  2204.  
  2205.                         hh = Get1Resource('BNDL', 128);
  2206.                         if (hh) {
  2207.                             CTEGetPStr(ctl, qstr);
  2208.                             BlockMove(qstr + 1, *hh + 0x00, sizeof(OSType));
  2209.                             ChangedResource(hh);
  2210.                             WriteResource(hh);
  2211.                         }
  2212.     
  2213.                         oldCreator[0] = 0;
  2214.                         CTEGetPStr(ctl, qstr);
  2215.                         VisCNum2Ctl(window, kOldAppWannabeCreator, &ctl);
  2216.                         if (ctl) {
  2217.                             pcpy(pstr, (*ctl)->contrlTitle);
  2218.                             BlockMove(pstr + 2, oldCreator + 1, (oldCreator[0] = sizeof(OSType)));
  2219.                         }
  2220.  
  2221.                         if (oldCreator[0]) {
  2222.                             hh = Get1Resource('STR#', 128);
  2223.                             if (hh) {
  2224.                                 UpdateHandle(hh, oldCreator, qstr, true);
  2225.                                 ChangedResource(hh);
  2226.                                 WriteResource(hh);
  2227.                             }
  2228.  
  2229.                             BlockMove(oldCreator + 1, &sft,  sizeof(OSType));
  2230.                             BlockMove(newCreator + 1, &sft2, sizeof(OSType));
  2231.  
  2232.                             hh = Get1Resource(sft, 0);
  2233.                             if (hh) DetachResource(hh);
  2234.                             h2 = Get1Resource(sft, 0);
  2235.                             if (h2) {
  2236.                                 RemoveResource(h2);
  2237.                                 DisposeHandle(h2);
  2238.                             }
  2239.  
  2240.                             if (hh) {
  2241.                                 pcpy(pstr, (StringPtr)(*hh));
  2242.                                 pp = pstr + oldPartName[0];
  2243.                                 pp[0] = pstr[0] - oldPartName[0];
  2244.                                 pcpy(qstr, newPartName);
  2245.                                 pcat(qstr, pp);
  2246.                                 pcpy(pstr, (StringPtr)(*hh));
  2247.                                 UpdateHandle(hh, pstr, qstr, true);
  2248.  
  2249.                                 AddResource(hh, sft2, 0, nil);
  2250.                                 ChangedResource(hh);
  2251.                                 WriteResource(hh);
  2252.                             }
  2253.                         }
  2254.  
  2255.                         pstr[0] = qstr[0] = 0;
  2256.                         VisCNum2Ctl(window, kAppWannabeDefDoc, &ctl);
  2257.                         if (ctl) CTEGetPStr(ctl, qstr);
  2258.                         VisCNum2Ctl(window, kOldAppWannabeDefDoc, &ctl);
  2259.                         if (ctl) {
  2260.                             pstr[0] = sizeof(OSType);
  2261.                             BlockMove((*ctl)->contrlTitle + 2, pstr + 1, sizeof(OSType));
  2262.                         }
  2263.                         if ((pstr[0]) && (qstr[0])) {
  2264.                             hh = Get1Resource('WFMT', 128);
  2265.                             if (hh) {
  2266.                                 BlockMove(pstr + 1, &sft, sizeof(OSType));
  2267.                                 wfmt = NewRootObj(ROOTOBJ, 0);
  2268.                                 HReadTree(wfmt, hh);
  2269.                                 for (ii = 0; ii < (*wfmt)->numChildren; ++ii) {
  2270.                                     wf = GetChildHndl(wfmt, ii);
  2271.                                     if (mDerefWFMT(wf)->sfType == sft) {
  2272.                                         BlockMove(qstr + 1, &sft, sizeof(OSType));
  2273.                                         mDerefWFMT(wf)->sfType = sft;
  2274.                                         break;
  2275.                                     }
  2276.                                 }
  2277.                                 SetHandleSize(hh, 0);    /* Should already be 0. */
  2278.                                 HWriteTree(wfmt, hh);
  2279.                                 DisposeObjAndOffspring(wfmt);
  2280.                                 ChangedResource(hh);
  2281.                                 WriteResource(hh);
  2282.                             }
  2283.                         }
  2284.                     }
  2285.  
  2286.                     VisCNum2Ctl(window, kAppWannabeDefDoc, &ctl);
  2287.                     if (ctl) {
  2288.                         hh = Get1Resource('FREF', 129);
  2289.                         if (hh) {
  2290.                             CTEGetPStr(ctl, qstr);
  2291.                             BlockMove(qstr + 1, *hh + 0x00, sizeof(OSType));
  2292.                             ChangedResource(hh);
  2293.                             WriteResource(hh);
  2294.                         }
  2295.                     }
  2296.                     VisCNum2Ctl(window, kAppWannabeCreator, &ctl);
  2297.                     if (ctl) {
  2298.                         hh = Get1Resource('STR ', -16396);
  2299.                         if (hh) {
  2300.                             UpdateHandle(hh, oldPartName, newPartName, true);
  2301.                             ChangedResource(hh);
  2302.                             WriteResource(hh);
  2303.                         }
  2304.                         hh = Get1Resource('vers', 1);
  2305.                         if (hh) {
  2306.                             pcpy(pstr, (StringPtr)(*hh + 0x06 + (*hh)[6] + 1));
  2307.                             pp = pstr + oldPartName[0];
  2308.                             pp[0] = pstr[0] - oldPartName[0];
  2309.                             pcpy(qstr, newPartName);
  2310.                             pcat(qstr, pp);
  2311.                             pcpy(pstr, (StringPtr)(*hh + 0x06 + (*hh)[6] + 1));
  2312.                             UpdateHandle(hh, pstr, qstr, true);
  2313.                             ChangedResource(hh);
  2314.                             WriteResource(hh);
  2315.                         }
  2316.                     }
  2317.                 }
  2318.             }
  2319.  
  2320.             if (date) {
  2321.                 pb.hFileInfo.ioNamePtr   = fss.name;
  2322.                 pb.hFileInfo.ioVRefNum   = fss.vRefNum;
  2323.                 pb.hFileInfo.ioDirID     = fss.parID;
  2324.                 pb.hFileInfo.ioFDirIndex = 0;    /* use ioNamePtr and ioDirID */
  2325.                 if (!PBGetCatInfoSync(&pb)) {
  2326.                     pb.hFileInfo.ioFlCrDat = ((long *)(*date))[0];
  2327.                     pb.hFileInfo.ioFlMdDat = ((long *)(*date))[1];
  2328.                     pb.hFileInfo.ioDirID   = fss.parID;
  2329.                     eee = PBSetCatInfoSync(&pb);
  2330.                 }
  2331.             }
  2332.  
  2333.             CloseResFile(refNum);
  2334.             UseResFile(oldRes);
  2335.         }
  2336.  
  2337. if (err) { pcpy(errstr, "\p### MMM err = $"); pcathex(errstr, err); DebugStr(errstr); }
  2338.         if (err) {
  2339.             DisplayControlSet(window, 'DUM2', kwHideAll);
  2340.             CNum2Ctl(window, kAboutCtlArea, &acc);
  2341.             if (acc) {
  2342.                 arr = (*acc)->contrlRect;
  2343.                 EraseRect(&arr);
  2344.                 InvalRect(&arr);
  2345.             }
  2346.             DisplayControlSet(window, 'DUM1', kwShowAll);
  2347.             return;
  2348.         }
  2349.  
  2350.         if (brk) break;
  2351.     }
  2352.  
  2353.     UseResFile(gAppResRef);
  2354.  
  2355.     Delay(30, &ll);
  2356.  
  2357.     DisplayControlSet(window, 'DUM2', kwHideAll);
  2358.     CNum2Ctl(window, kAboutCtlArea, &acc);
  2359.     if (acc) {
  2360.         arr = (*acc)->contrlRect;
  2361.         EraseRect(&arr);
  2362.         InvalRect(&arr);
  2363.     }
  2364.     DisplayControlSet(window, 'DUM1', kwShowAll);
  2365. }
  2366.  
  2367. static void    FixupAliases(WindowPtr window)
  2368. {
  2369.     short            ii, jj, srcFolderPathLen, dstFolderPathLen, oldRes, res;
  2370.     AliasHandle        aa;
  2371.     FSSpec            **fssh, fss, targetfss;
  2372.     Str255            p1, p2;
  2373.     StringPtr        pptr;
  2374.     OSErr            err;
  2375.     Boolean            wasChanged;
  2376.     static Str255    aliasPath, aliasName, fsPath, fsName;
  2377.  
  2378.     fssh = gFSSpec[0].fss;
  2379.     if (!fssh) return;
  2380.  
  2381.     fss = **fssh;
  2382.     if (FullPathFromFSSpec(&fss, fsPath, fsName)) return;
  2383.     dstFolderPathLen = fsPath[0] + 1;
  2384.  
  2385.     for (ii = 0; ii < gResolveIndx; ++ii) {
  2386.         aa = gAlias[ii];
  2387.         if (!aa) continue;
  2388.  
  2389.         if (FullPathFromAlias(aa, aliasPath, aliasName)) continue;
  2390.         srcFolderPathLen = aliasPath[0] - aliasName[0];
  2391.  
  2392.         for (jj = 0; jj < gResolveIndx; ++jj) {
  2393.             fssh = gFSSpec[jj].fss;
  2394.             if (!fssh) continue;
  2395.  
  2396.             fss = **fssh;
  2397.             if (FullPathFromFSSpec(&fss, fsPath, fsName)) continue;
  2398.  
  2399.             if (aliasPath[0] <= srcFolderPathLen)     continue;
  2400.             if (fsPath[0]    <= dstFolderPathLen)     continue;
  2401.             if (pcmp(aliasName, gFSSpec[jj].oldName)) continue;
  2402.  
  2403.             p1[0] = fsPath[0] - dstFolderPathLen;
  2404.             BlockMove(fsPath + dstFolderPathLen + 1, p1 + 1, p1[0]);
  2405.             for (; p1[0]; --p1[0]) if (p1[p1[0]] == ':') break;
  2406.             pcat(p1, gFSSpec[jj].oldName);
  2407.  
  2408.             if (p1[0] > aliasPath[0]) continue;
  2409.  
  2410.             p2[0] = p1[0];
  2411.             BlockMove(aliasPath + 1 + (aliasPath[0] - p2[0]), p2 + 1, p2[0]);
  2412.  
  2413.             if (pcmp(p1, p2)) continue;
  2414.  
  2415.             fssh = gFSSpec[ii].fss;
  2416.             if (!fssh) continue;
  2417.             fss = **fssh;
  2418.  
  2419.             oldRes = CurResFile();
  2420.             res    = HOpenResFile(fss.vRefNum, fss.parID, fss.name, fsRdWrPerm);
  2421.             if (ResError()) continue;
  2422.             aa = (AliasHandle)Get1Resource('alis', 0);
  2423.             if (aa) {
  2424.                 pptr = fsPath;
  2425.                 for (;;) {
  2426.                     if (!pptr[0]) break;
  2427.                     if (pptr[1] == ':') {
  2428.                         err = FSMakeFSSpec(fss.vRefNum, fsRtDirID, pptr, &targetfss);
  2429.                         err = UpdateAlias(&fss, &targetfss, aa, &wasChanged);
  2430.                         ChangedResource((Handle)aa);
  2431.                         WriteResource((Handle)aa);
  2432.                         break;
  2433.                     }
  2434.                     pptr[1] = pptr[0] - 1;
  2435.                     ++pptr;
  2436.                 }
  2437.             }
  2438.             CloseResFile(res);
  2439.             UseResFile(oldRes);
  2440.         }
  2441.     }
  2442.  
  2443.     for (ii = 0; ii < gResolveIndx; ++ii) {
  2444.         aa = gAlias[ii];
  2445.         if (aa) {
  2446.             DisposeHandle((Handle)aa);
  2447.             gAlias[ii] = nil;
  2448.         }
  2449.         fssh = gFSSpec[ii].fss;
  2450.         if (fssh) {
  2451.             DisposeHandle((Handle)fssh);
  2452.             gFSSpec[ii].fss = nil;
  2453.         }
  2454.     }
  2455.  
  2456.     gResolveIndx = 0;
  2457. }
  2458.  
  2459. static OSErr    FullPathFromAlias(AliasHandle alias, StringPtr aliasPath, StringPtr aliasName)
  2460. {
  2461.     OSErr            result;
  2462.     AliasInfoType    index;
  2463.     Str255            nodeName, temp;
  2464.     
  2465.     /* Get partial pathname */
  2466.     aliasPath[0] = 0;
  2467.     index = asiAliasName;
  2468.     do
  2469.     {
  2470.         result = GetAliasInfo(alias, index, nodeName);
  2471.         if ( (result == noErr) && (nodeName[0] != 0) )
  2472.         {
  2473.             pcpy(temp, aliasPath);
  2474.             pcpy(aliasPath, "\p:");
  2475.             pcat(aliasPath, nodeName);
  2476.             pcat(aliasPath, temp);
  2477.             if (!index) pcpy(aliasName, nodeName);
  2478.         }
  2479.         ++index;
  2480.     } while ( (result != noErr) || (nodeName[0] != 0) );
  2481.     
  2482.     if (result == noErr)
  2483.     {
  2484.         /* Add volume name */
  2485.         result = GetAliasInfo(alias, asiVolumeName, nodeName);
  2486.         if ( result == noErr )
  2487.         {
  2488.             pcpy(temp, aliasPath);
  2489.             pcpy(aliasPath, nodeName);
  2490.             pcat(aliasPath, temp);
  2491.         }
  2492.     }
  2493.     return ( result );
  2494. }
  2495.  
  2496. static    OSErr    FullPathFromFSSpec(const FSSpec *spec, StringPtr fsPath, StringPtr fsName)
  2497. {
  2498.     OSErr        result;
  2499.     CInfoPBRec    pb;
  2500.     Str255        nodeName, temp;
  2501.     
  2502.     fsPath[0] = 0;
  2503.     
  2504.     /* Build a full pathname down to the volume */
  2505.     pb.dirInfo.ioNamePtr = nodeName;
  2506.     pb.dirInfo.ioVRefNum = spec->vRefNum;
  2507.     pb.dirInfo.ioDrParID = spec->parID;
  2508.     do
  2509.     {
  2510.         pb.dirInfo.ioFDirIndex = -1;
  2511.         pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
  2512.         result = PBGetCatInfoSync(&pb);
  2513.         pcpy(temp, fsPath);
  2514.         pcpy(fsPath, nodeName);
  2515.         pcat(fsPath, "\p:");
  2516.         pcat(fsPath, temp);
  2517.     } while ( (result == noErr) && (pb.dirInfo.ioDrDirID != fsRtDirID) );
  2518.     
  2519.     /* add the spec's name field and we're done */
  2520.     pcat(fsPath, (StringPtr)spec->name);
  2521.  
  2522.     pcpy(fsName, (StringPtr)spec->name);
  2523.     return ( result );
  2524. }
  2525.  
  2526.  
  2527.  
  2528. /*****************************************************************************/
  2529. /*****************************************************************************/
  2530. /*****************************************************************************/
  2531.  
  2532.  
  2533.  
  2534. // This code goes into a separate segment due to the way that PartMaker is shipped.
  2535. // The internal version of PartMaker can create PartMaker documents.  We don't
  2536. // ship this version.  To make a shippable version, do the following:
  2537. // • Use AppsToGo Editor to delete the 'fold' entry (optional).
  2538. // • Use ResEdit to remove the 'fold' 'BNDL' entry.
  2539. // • Use ResEdit to remove the "AppleOnly" 'CODE' resource.
  2540. // After the above steps, the ability to turn folders into projects has been removed.
  2541.  
  2542. OSErr    CacheFile(FSSpec out, FSSpec in, short *oldDepth, short newDepth)
  2543. {
  2544.     OSErr        err = noErr;
  2545.     short        oldRes, outRes, inRes, inRef;
  2546.     long        eof, date[2];
  2547.     Handle        hndl;
  2548.     Boolean        isFolder;
  2549.     FInfo        finfo, fff;
  2550.     DInfo        dinfo;
  2551.     Str255        pstr;
  2552.     CInfoPBRec    pb;
  2553.  
  2554.     oldRes = CurResFile();
  2555.  
  2556.     isFolder = false;
  2557.     err = GetDInfo(in.vRefNum, in.parID, in.name, &dinfo);
  2558.     if (!err) isFolder = true;
  2559.     if (!isFolder) {
  2560.         HGetFInfo(in.vRefNum, in.parID, in.name, &finfo);
  2561.         if (finfo.fdCreator == 'MPS ') {
  2562.             if (finfo.fdType == 'OBJ ') return(noErr);
  2563.             if (finfo.fdType == 'XCOF') return(noErr);
  2564.         }
  2565.         if (finfo.fdCreator == 'MWDB') {
  2566.             if (finfo.fdType == 'MMPF') return(noErr);
  2567.             if (finfo.fdType == 'MPSY') return(noErr);
  2568.         }
  2569.     }
  2570.  
  2571.     outRes = HOpenResFile(out.vRefNum, out.parID, out.name, fsRdWrPerm);
  2572.     err    = ResError();
  2573.     if (err) {
  2574.         if ((err != eofErr) && (err != fnfErr)) {
  2575.             UseResFile(oldRes);
  2576.             return(err);
  2577.         }
  2578.         HCreateResFile(out.vRefNum, out.parID, out.name);
  2579.         err = ResError();
  2580.         if (err) {
  2581.             UseResFile(oldRes);
  2582.             return(err);
  2583.         }
  2584.         outRes = HOpenResFile(out.vRefNum, out.parID, out.name, fsRdWrPerm);
  2585.         err    = ResError();
  2586.         if (err) {
  2587.             CloseResFile(outRes);
  2588.             UseResFile(oldRes);
  2589.             return(err);
  2590.         }
  2591.     }
  2592.  
  2593.     HGetFInfo(out.vRefNum, out.parID, out.name, &fff);
  2594.     fff.fdCreator = gSignature;
  2595.     fff.fdType    = 'PtMd';
  2596.     HSetFInfo(out.vRefNum, out.parID, out.name, &fff);
  2597.  
  2598.     for (; *oldDepth > newDepth; --*oldDepth) {
  2599.         hndl = NewHandle(3);
  2600.         pcpy((StringPtr)*hndl, "\p::");
  2601.         AddResource(hndl, 'STR ', gRsrcNum++, nil);
  2602.         ChangedResource(hndl);
  2603.         WriteResource(hndl);
  2604.         DetachResource(hndl);
  2605.         DisposeHandle(hndl);
  2606.     }
  2607.  
  2608.     if (isFolder) {
  2609.         pcpy(pstr, in.name);
  2610.         pcpy(in.name, "\p:");
  2611.         pcat(in.name, pstr);
  2612.         ++newDepth;
  2613.     }
  2614.     *oldDepth = newDepth;
  2615.  
  2616.     hndl = NewHandle(in.name[0] + 1);
  2617.     pcpy((StringPtr)*hndl, in.name);
  2618.     AddResource(hndl, 'STR ', gRsrcNum, nil);
  2619.     ChangedResource(hndl);
  2620.     WriteResource(hndl);
  2621.     DetachResource(hndl);
  2622.     DisposeHandle(hndl);
  2623.  
  2624.     if (!isFolder) {
  2625.         hndl = NewHandle(sizeof(FInfo));
  2626.         BlockMove(&finfo, *hndl, sizeof(FInfo));
  2627.         AddResource(hndl, 'fINO', gRsrcNum, nil);
  2628.         ChangedResource(hndl);
  2629.         WriteResource(hndl);
  2630.         DetachResource(hndl);
  2631.         DisposeHandle(hndl);
  2632.     }
  2633.     else {
  2634.         hndl = NewHandle(sizeof(DInfo));
  2635.         BlockMove(&dinfo, *hndl, sizeof(DInfo));
  2636.         AddResource(hndl, 'dINO', gRsrcNum, nil);
  2637.         ChangedResource(hndl);
  2638.         WriteResource(hndl);
  2639.         DetachResource(hndl);
  2640.         DisposeHandle(hndl);
  2641.     }
  2642.  
  2643.     pb.hFileInfo.ioNamePtr   = in.name;
  2644.     pb.hFileInfo.ioVRefNum   = in.vRefNum;
  2645.     pb.hFileInfo.ioDirID     = in.parID;
  2646.     pb.hFileInfo.ioFDirIndex = 0;    /* use ioNamePtr and ioDirID */
  2647.     if (!PBGetCatInfoSync(&pb)) {
  2648.         date[0] = pb.hFileInfo.ioFlCrDat;
  2649.         date[1] = pb.hFileInfo.ioFlMdDat;
  2650.         hndl = NewHandle(2 * sizeof(long));
  2651.         BlockMove(&date[0], *hndl, 2 * sizeof(long));
  2652.         AddResource(hndl, 'date', gRsrcNum, nil);
  2653.         ChangedResource(hndl);
  2654.         WriteResource(hndl);
  2655.         DetachResource(hndl);
  2656.         DisposeHandle(hndl);
  2657.     }
  2658.  
  2659.     gRsrcNum++;
  2660.  
  2661.     if (isFolder) {
  2662.         CloseResFile(outRes);
  2663.         UseResFile(oldRes);
  2664.         return(noErr);
  2665.     }
  2666.  
  2667.     err = HOpenDF(in.vRefNum, in.parID, in.name, fsRdPerm, &inRef);
  2668.     if (err) {
  2669.         CloseResFile(outRes);
  2670.         UseResFile(oldRes);
  2671.         return(err);
  2672.     }
  2673.  
  2674.     err = GetEOF(inRef, &eof);
  2675.     if (err) {
  2676.         FSClose(inRef);
  2677.         CloseResFile(outRes);
  2678.         UseResFile(oldRes);
  2679.         return(err);
  2680.     }
  2681.  
  2682.     SetFPos(inRef, fsFromStart, 0);
  2683.     hndl = NewHandle(eof);
  2684.     HLock(hndl);
  2685.     err = FSRead(inRef, &eof, *hndl);
  2686.     HUnlock(hndl);
  2687.     FSClose(inRef);
  2688.     AddResource(hndl, 'dFRK', gRsrcNum - 1, nil);
  2689.     ChangedResource(hndl);
  2690.     WriteResource(hndl);
  2691.     DetachResource(hndl);
  2692.     DisposeHandle(hndl);
  2693.  
  2694.     err = HOpenRF(in.vRefNum, in.parID, in.name, fsRdPerm, &inRes);
  2695.     if (err) {
  2696.         CloseResFile(outRes);
  2697.         UseResFile(oldRes);
  2698.         return(err);
  2699.     }
  2700.  
  2701.     err = GetEOF(inRes, &eof);
  2702.     if (err) {
  2703.         FSClose(inRes);
  2704.         CloseResFile(outRes);
  2705.         UseResFile(oldRes);
  2706.         return(err);
  2707.     }
  2708.  
  2709.     SetFPos(inRes, fsFromStart, 0);
  2710.     hndl = NewHandle(eof);
  2711.     HLock(hndl);
  2712.     err = FSRead(inRes, &eof, *hndl);
  2713.     HUnlock(hndl);
  2714.     FSClose(inRes);
  2715.     AddResource(hndl, 'rFRK', gRsrcNum - 1, nil);
  2716.     ChangedResource(hndl);
  2717.     WriteResource(hndl);
  2718.     DetachResource(hndl);
  2719.     DisposeHandle(hndl);
  2720.  
  2721.     HGetFInfo(in.vRefNum, in.parID, in.name, &finfo);
  2722.  
  2723.     hndl = NewHandle(sizeof(OSType));
  2724.     BlockMove(&finfo.fdCreator, *hndl, sizeof(OSType));
  2725.     AddResource(hndl, 'cTYP', gRsrcNum - 1, nil);
  2726.     ChangedResource(hndl);
  2727.     WriteResource(hndl);
  2728.     DetachResource(hndl);
  2729.     DisposeHandle(hndl);
  2730.  
  2731.     hndl = NewHandle(sizeof(OSType));
  2732.     BlockMove(&finfo.fdType, *hndl, sizeof(OSType));
  2733.     AddResource(hndl, 'tTYP', gRsrcNum - 1, nil);
  2734.     ChangedResource(hndl);
  2735.     WriteResource(hndl);
  2736.     DetachResource(hndl);
  2737.     DisposeHandle(hndl);
  2738.  
  2739.     CloseResFile(outRes);
  2740.     UseResFile(oldRes);
  2741.  
  2742.     return(err);
  2743. }
  2744.  
  2745.  
  2746.  
  2747. static void        IndCNum2Ctl(WindowPtr window, short ctlNum, short cset, ControlHandle *ctl)
  2748. {
  2749.     short    cid;
  2750.  
  2751.     *ctl = nil;
  2752.     if (!ctlNum) return;
  2753.  
  2754.     cid = ctlNum;    /* Caller may have actually passed us a cid. */
  2755.  
  2756.     *ctl = ((WindowPeek)window)->controlList;
  2757.     for (;;) {
  2758.         if (!*ctl) break;
  2759.         if (GetControlID(*ctl) == cid) {
  2760.             --cset;
  2761.             if (cset < 1) return;
  2762.         }
  2763.         *ctl = (**ctl)->nextControl;
  2764.     }
  2765.  
  2766.     return;
  2767. }
  2768.  
  2769. static void        VisCNum2Ctl(WindowPtr window, short ctlNum, ControlHandle *ctl)
  2770. {
  2771.     short    cid;
  2772.  
  2773.     *ctl = nil;
  2774.     if (!ctlNum) return;
  2775.  
  2776.     cid = ctlNum;    /* Caller may have actually passed us a cid. */
  2777.  
  2778.     *ctl = ((WindowPeek)window)->controlList;
  2779.     for (;;) {
  2780.         if (!*ctl) break;
  2781.         if (GetControlID(*ctl) == cid) {
  2782.             if ((**ctl)->contrlVis) {
  2783.                 return;
  2784.             }
  2785.         }
  2786.         *ctl = (**ctl)->nextControl;
  2787.     }
  2788.  
  2789.     CNum2Ctl(window, ctlNum, ctl);
  2790.  
  2791.     return;
  2792. }
  2793.  
  2794.